Django使用UserProfile形成问题

时间:2012-08-17 13:26:42

标签: django forms

我想创建一个“更新用户的个人资料”页面,让用户修改他们的个人资料,所以我想出了以下模型:

class Profile(models.Model):
    user = models.OneToOneField(User)

    nick_name = models.CharField(blank=True,max_length=100)
    school = models.CharField(blank=True,max_length=100)
    motto = models.CharField(blank=True,max_length=100)

class ProfileForm(ModelForm):
    class Meta:
        model = Profile

我的观点设计为:

@login_required
def update_profile_view(request):
    if request.method == 'POST':
        user = request.user
        try:
            profile = user.get_profile()
        except Exception:
            profile = Profile.objects.create(user=user)
        form = ProfileForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            profile.nick_name = cd['nick_name']
            profile.school = cd['school']
            profile.motto = cd['motto']
            profile.save()
            return HttpResponseRedirect('/main_page/')
    else:
        form = ProfileForm()
    return render(request, 'update_profile.html', {'form':form})

用户和个人资料之间的关系显然是1到1,并且根据请求我可以确定当前用户。因此不需要填写表单的用户字段。不幸的是,这无法通过“form.is_valid()”测试。并且在调用“is_valid”之前修改表单似乎很难。为简单起见,我不想创建自己的表单类,也不想编写自定义表单验证。有没有其他方法可以解决这个问题?

3 个答案:

答案 0 :(得分:3)

您的观点可以大大简化:

@login_required
def update_profile_view(request):
    try:
        profile = Profile.objects.get(user=request.user)
    except Profile.DoesNotExist:
        profile = None

    form = ProfileForm(request.POST or None, instance=profile)

    if request.method == 'POST':            
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/main_page/')
    return render(request, 'update_profile.html', {'form':form})

无需像您一样手动分配字段。 Django ORM知道如何自动执行插入与更新。因此,如果您只是将ProfileForm的一个实例传递给ProfileForm,它就知道要进行更新。如果没有配置文件的实例,它将进行插入。

现在,如果您想在UI中对用户进行透明分配,则需要从表单中排除user字段并自行分配。有几种不同的方法可以做到这一点。

我还建议您在重定向中使用reverse,这样您就没有硬编码路径。

答案 1 :(得分:3)

您基本上有两种选择:

1 ProfileForm的修改:

    class ProfileForm(ModelForm):
        class Meta:
            model = Profileclass
            exclude = ('user',)

2更改以下行:

form = ProfileForm(request.POST, instance=profile)
if form.is_valid():
    updated_profile = form.save()

答案 2 :(得分:0)

您可以将用户字段的值设置为表单的init方法中不需要的值(self.fields ['user'] .require = False),或者将用户设置为不可编辑的模型(editable = False)。

在view方法中,调用profile = form.save(commit = False),然后执行profile.user = your_user和profile.save()

由于ModelForm会执行此操作,因此您无需手动将已清理的数据应用于配置文件。