UserProfile id == None 在表单验证/保存

UserProfile id == None in form validation / save

在编辑用户配置文件的 django 视图函数中,我在保存时看到 id==None。表格和模型均未明确提及 UserProfile.id 或 User.id。 UserProfile 模型有这条典型的线

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

表格这样结束:

class Meta:
    """Provide an association between ModelForm and model."""
    model = UserProfile
    fields = ('address', 'postal_code', 'city', 'country', 'date_of_birth')

一切看起来都很简单,但在保存时,我看到了完整性违规。该数据库是一个有两个用户的测试数据库,我很确定,通过对两个条目的详尽检查,id 字段没问题。

def edit_profile(request):
    """Edit/create a user's profile."""
    if request.method == 'POST':
        form = ProfileForm(request.POST)
        if form.is_valid():
            print(form.cleaned_data) # looks reasonable
            profile = form.save(commit=False)
            # profile.user = User.objects.get(id=request.user.id)
            profile.user = request.user
            print('id=', profile.id) # Why is this None?
            # On save, we'll get Integrity error,
            # UNIQUE constraint failed: kernel_userprofile.user_id
            profile.save() # Integrity error
            print('form saved')
            return HttpResponseRedirect(reverse('kernel/profile'))
        # TODO(jeff@purple.com): Debug only, at most.
        print(form.errors)
    else:
        my_profile = UserProfile.objects.get(user=request.user)
        form = ProfileForm(instance=my_profile)

    return render(request, 'kernel/profilemod.html', {'form': form})

有什么指点吗?

profile.id 字段在 profile.save() 方法中设置,然后 profile 第一次创建。

IntegrityError 被引发是因为您试图创建新的 UserProfile 而不是保存旧的。要解决此问题,您应该将 instance 参数传递给 ProfileForm 构造函数:

form = ProfileForm(request.POST,
                   instance=UserProfile.objects.get(user=request.user))

EDIT:如果您想编辑 在单个视图中创建个人资料,然后使用 first() 而不是阅读个人资料进行编辑get():

def edit_profile(request):
    profile = UserProfile.objects.filter(user=request.user).first()
    if request.method == 'POST':
        form = ProfileForm(request.POST, instance=profile)
        if form.is_valid():
            ...
    else:
        form = ProfileForm(instance=profile)