在使用ModelForm创建的表单对象中设置用户字段

2 投票
3 回答
1028 浏览
提问于 2025-04-17 11:54

我有一个注册表单,当用户输入有效的注册信息后,它会让用户登录,并把用户重定向到另一个表单,以便输入更多信息。这个新表单包含了关于用户的更多数据,是用下面的ModelForm类创建的:

class UserProfileAddForm(ModelForm):
    class Meta:
        model = UserProfile
        exclude = ('user')

而UserProfile模型看起来是这样的:

class UserProfile(models.Model):
    GRADE_YEAR_CHOICES = (
        ('FR', 'Freshman'),
        ('SO', 'Sophomore'),
        ('JR', 'Junior'),
        ('SR', 'Senior'),
        ('GR', 'Graduate')
    )

    school = models.CharField(max_length=64)
    grade_year = models.CharField(max_length=2, choices=GRADE_YEAR_CHOICES)
    gpa = models.DecimalField(decimal_places=2, max_digits=6, blank=True, null=True)
    user = models.ForeignKey(User, unique=True)

其中,用户字段是指向Django的用户对象的外键。我在设置用户字段为发起请求的用户时遇到了困难。以下是我在views.py中尝试过的内容:

第一次尝试:

def more(request):
    if request.method == 'POST':
        form = UserProfileAddForm(request.POST)
        if form.is_valid():
            form.save(commit=False)
            form.user = request.user
            form.save()
            return HttpResponseRedirect('/register/success/')
    else:
        form = UserProfileAddForm()
        variables = RequestContext(request, {
            'form': form

第二次尝试:

def more(request):
    if request.method == 'POST':
        form = UserProfileAddForm(request.POST)
        if form.is_valid():
            form.save(commit=False)
            form.user = User.objects.filter(username=request.user)
            form.save()
            return HttpResponseRedirect('/register/success/')
    else:
        form = UserProfileAddForm()
        variables = RequestContext(request, {
            'form': form
        })
        return render_to_response('registration/more.html', variables)

无论我怎么尝试,似乎都无法将数据保存到数据库中。不过,它会把我重定向到成功页面,就好像确实保存成功了一样。

3 个回答

0

好吧,你需要明白的是,当你执行以下操作时,你会得到一个模型实例,也就是在你的情况下:

profile = form.save(commit =False)

然后,当你保存这个模型对象时,它并不会保存任何多对多的关系。这一点你需要在保存模型对象之后再处理。通过这样做:

form.save_m2m()

所以,在你保存完模型对象之后,只需添加最后一段代码就可以了。

1

我的建议是你在第二次尝试时做这个更改:

        with_profile = form.save(commit=False)
        with_profile.user = request.user
        form.save()
        ...

问题在于你把 user 属性添加到了 form 对象上,而不是 form.instance 对象上。

编辑过的内容

当我第一次回答时,我在用户分配上犯了个错误。@Dirk 在下面评论了这个问题,现在已经修正了。感谢 @Dirk。问题是一个查询集被分配给了 with_profile.user,而不是一个单独的模型。

2

form.save() 会返回一个正在保存的模型实例。在这里,你需要设置用户,然后再保存这个实例。

profile = form.save(commit=False)
profile.user = request.user
profile.save()

需要注意的是,根据 request.user 的值从数据库中获取用户是没有意义的,因为 request.user 本身就是正确的用户对象。

撰写回答