Django - 重复键值违反唯一约束

Django - duplicate key value violates unique constraint

在我的 Django 项目中,我创建了一个应用程序来获取有关注册用户的其他信息。所以我的模型看起来像这样:

class UserProfile(models.Model):
   class Meta:
      verbose_name_plural = u'User Profile'

   user = models.OneToOneField(User)
   birthday = models.DateField(blank=True, null=True)
   avatar = models.ImageField(upload_to='media/profile/avatar', blank=True, null=True)
   name = models.CharField(blank=True, null=True, max_length=20)
   surname = models.CharField(blank=True, null=True, max_length=50)
   phone = models.CharField(blank=True, null=True, max_length=12)

   def __unicode__(self):
      return '%s' % self.user

这是我的注册表:

class RegistrationForm(ModelForm):
   username = forms.CharField(label=(u'Username'))
   email = forms.EmailField(label=(u'Email'))
   password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
   password1 = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))

   class Meta:
      model = UserProfile
      exclude = ('user',)
      fields = ('username', 'email', 'password', 'password1')

   def clean_email(self):
      email = self.cleaned_data['email']
      try:
         User.objects.get(email=email)
      except User.DoesNotExist:
         return email
      raise forms.ValidationError("User with same email already exist, please change your email")

这是我的注册表单视图:

def UserProfileRegistration(request):
   if request.user.is_authenticated():
      return HttpResponseRedirect('/profile/')
   if request.method == 'POST':
      form = RegistrationForm(request.POST)
         if form.is_valid():
            user = User.objects.create_user(username=form.cleaned_data['username'], email=form.cleaned_data['email'], password=form.cleaned_data['password'])
            user.save()
            user_profile = UserProfile(user=user)
            user_profile.save()
            return HttpResponseRedirect('/profile/')
         else:
            return render(request, 'profiles/registration.html', {'form':form})
        else:
            form = RegistrationForm()
            context = {'form':form}
            return render (request, 'profiles/registration.html', context)

在用户配置文件中,我创建了模型表单,用户可以在其中填写 UserProfile 模型中的字段:

class ExtraProfileDataForm(ModelForm):
   name = forms.CharField(label=(u'Enter your name'))
   surname = forms.CharField(label=(u'Enter your surname'))
   phone = forms.CharField(label=(u'Enter your phone'))
   birthday = forms.DateField(label=(u'Enter birthday'))
   avatar = forms.ImageField(label=(u'Enter avatar'))

   class Meta:
      model = UserProfile
      fields = ('name', 'surname', 'phone', 'birthday', 'avatar')

   def __init__(self, *args, **kwargs):
      super(ExtraProfileDataForm, self).__init__(*args, **kwargs)
         for key in self.fields:
            self.fields[key].required = False

这是模型窗体的视图:

@login_required
def UserFullDataForm(request):
   if request.method == 'POST':
      form = ExtraProfileDataForm(request.POST)
         if form.is_valid():
            profile_user = request.user
            user_profile = UserProfile(user=profile_user)
            user_profile.name = form.cleaned_data['name']
            user_profile.surname = form.cleaned_data['surname']
            user_profile.phone = form.cleaned_data['phone']
            user_profile.birthday = form.cleaned_data['birthday']
            user_profile.avatar = form.cleaned_data['avatar']
            user_profile.save()
            return HttpResponseRedirect('/profile/')
          else:
            return render(request, 'profiles/extra_profile.html', {'form':form})
        else:
            form = ExtraProfileDataForm()
            context = {'form':form}
            return render (request, 'profiles/extra_profile.html', context)

但是当我填写此表格时出现错误: duplicate key value violates unique constraint "profiles_userprofile_user_id_key" DETAIL: Key (user_id)=(23) already exists. 在回溯中,我在这一行 user_profile.save() 中看到了该错误。据我了解,这是因为此脚本创建了具有相同 ID 的新项目但未对其进行更新。我必须更改我的代码以更新现有项目而不是创建。谢谢你。

您需要使用 get_or_create,这将 return 找到现有项目;否则创建模型的新实例。

在您的用户个人资料更新视图中:

user_profile, created = UserProfile.objects.get_or_create(user=profile.user)

现在,不是每次都创建新的配置文件 - 如果该用户的配置文件已经存在,您将进行更新。