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

时间:2016-02-29 08:26:13

标签: python django django-forms

在我的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的新项目,但没有更新它。我需要更改我的代码来更新现有项目而不是创建。谢谢。

1 个答案:

答案 0 :(得分:2)

您需要使用get_or_create,如果找到现有项目,则会返回该项目;否则创建一个新的模型实例。

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

meteor packages

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