【问题标题】:Saving Django User in Form在表单中保存 Django 用户
【发布时间】:2012-02-25 00:26:57
【问题描述】:

我目前正在开发我的第一个 Django 应用程序,它允许注册用户通过基本表单提交内容。

到目前为止,它有一个警告:当显示表单时,会向用户(“作者”)显示所有用户的下拉列表,而不是使用用户名自动填充该字段。这显然是不能接受的。

此目标是让注册用户的姓名自动填充表单。我已经看到了一些针对类似问题的各种潜在解决方案,但没有任何东西可以解决这个具体问题。

我尝试将模型中的 Author 字段设置为“unique=True”,但在迁移时导致数据库错误。

任何见解将不胜感激:

型号:

class Story(models.Model):
    title = models.CharField(max_length=100)
    topic = models.CharField(max_length=50)
    copy = models.TextField()
    author = models.ForeignKey(User)
    zip_code = models.CharField(max_length=10)
    latitude = models.FloatField(blank=False, null=False)
    longitude = models.FloatField(blank=False, null=False)
    date = models.DateTimeField(auto_now=True, auto_now_add=True)   
    def __unicode__(self):
         return " %s" % (self.title)

表格:

class StoryForm(forms.ModelForm):
class Meta:
    model = Story

查看:

@login_required
 def submit_story(request):
if request.method == "GET":
    story_form = StoryForm()
    return render_to_response("report/report.html",
                             {'form': story_form},
                              context_instance=RequestContext(request))
elif request.method =="POST":
    story_form = StoryForm(request.POST) 
    if story_form.is_valid():
        new_story = Story()
        new_story.title = story_form.cleaned_data["title"]
        new_story.topic = story_form.cleaned_data["topic"]
        new_story.copy = story_form.cleaned_data["copy"]
        new_story.author = request.user
        new_story.zip_code = story_form.cleaned_data["zip_code"]
        new_story.latitude = story_form.cleaned_data["latitude"]
        new_story.longitude = story_form.cleaned_data["longitude"]
        new_story.save()
        return HttpResponseRedirect("/report/all/")
    else:
        story_form = StoryForm()
        return render_to_response("report/report.html",
                                {'form': story_form},
                                 context_instance=RequestContext(Request))

编辑:我想我找到了相对简单的答案:我只是从表单中删除了“作者”字段并保持视图不变。我可以通过这种方式以注册用户的名义发帖。我认为这可行,除非我不知道(很多)是不正确或错误的协议。

【问题讨论】:

    标签: django django-models django-forms


    【解决方案1】:

    我设法做了类似的事情:

    与用户关联的所有模型的基类:

    class UserOwnedModel(models.Model):
        user = models.ForeignKey(User, editable=True)
    
        class Meta:
            abstract = True
    

    与用户关联的所有表单的基类:

    class UserOwnedForm(forms.ModelForm):
        exclude = ["user", ]
    
        def __init__(self, user, data=None, *arguments, **keywords):
            if data:
                data['user'] = user.id
                forms.ModelForm.__init__(self, data=data, *arguments, **keywords)
    

    我不确定这是否是最好的解决方案(如果有任何意见或建议,我会很高兴),但它对我有用。 这当然会从表单中完全删除用户字段,因此如果您需要显示用户名,则必须使用代码。


    编辑

    另外,不要这样:

    new_story = Story()
    new_story.title = story_form.cleaned_data["title"]
    new_story.topic = story_form.cleaned_data["topic"]
    new_story.copy = story_form.cleaned_data["copy"]
    new_story.author = request.user
    new_story.zip_code = story_form.cleaned_data["zip_code"]
    new_story.latitude = story_form.cleaned_data["latitude"]
    new_story.longitude = story_form.cleaned_data["longitude"]
    new_story.save()
    

    你可以这样做:

    new_story = story_form.save()
    

    编辑 2

    类似这样的:

    class Story(UserOwnedModel):
        title = models.CharField(max_length=100)
        topic = models.CharField(max_length=50)
        copy = models.TextField()
        zip_code = models.CharField(max_length=10)
        latitude = models.FloatField(blank=False, null=False)
        longitude = models.FloatField(blank=False, null=False)
        date = models.DateTimeField(auto_now=True, auto_now_add=True)   
        def __unicode__(self):
             return " %s" % (self.title)
    
    class StoryForm(UserOwnedForm):
        class Meta:
            model = Story
    
    @login_required
    def submit_story(request):
        if request.method == "GET":
            story_form = StoryForm(user=request.user)
        ....
        elif request.method =="POST":
            story_form = StoryForm(data=request.POST, user=request.user)
            if story_form.is_valid():
                new_story = story_form.save()
                .....
            else:
                story_form = StoryForm(user=request.user)
                ....
    

    我还稍微更改了我的初始代码。

    【讨论】:

    • 有趣的解决方案。您是否对暴露所有用户的下拉菜单有同样的问题?就这样结束了吗?此外,您的编辑是否需要保存表单,或者更适合使用直接从模型创建的表单?
    • 您会看到下拉选择菜单,因为它是 ForeignKey 字段的默认小部件,是的,我也有。我不想将用户名放在表单中,因为用户很清楚他的名字是什么,因此我的代码将其从表单中删除(用于显示)。不,这不是必需的,但在表单对象本身中这样做更面向对象。
    • 优秀。并使用您的方法,它会自动使用注册用户的姓名填充用户字段?如果是这样,那将接近完美。
    • 嗯,几乎,您需要做的就是使用额外的用户参数构造表单,例如:StoryForm(data=request.POST, user=request.user)StoryForm(user=request.user).
    • 哦,为了清楚起见忘记了一些东西。您的基本用户模型是一个新的独立模型,对吗?表单模型也一样?我的示例中的 StoryForm 将使用: StoryForm(UserOwnedModel): 或类似的东西?
    猜你喜欢
    • 2019-05-25
    • 1970-01-01
    • 2020-12-06
    • 2020-10-16
    • 2018-01-11
    • 2013-11-09
    • 1970-01-01
    • 2014-09-07
    • 2021-05-21
    相关资源
    最近更新 更多