2016-02-29 3 views
0

В моем проекте Django я создаю приложение, чтобы иметь дополнительную информацию о зарегистрированных пользователях. Так что моя модель выглядит следующим образом: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) 

В профиле пользователя я создать ModelForm где пользователь может заполнить поля из модели 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. На TRACEBACK я вижу, что ошибка в этой строке user_profile.save(). Как я понимаю, это происходит потому, что этот скрипт создает новый элемент с тем же идентификатором, но не обновляет его. Что мне нужно изменить в моем коде для обновления существующего элемента, но не для создания. Спасибо.

ответ

2

Вам необходимо использовать get_or_create, который вернет существующий элемент, если он был найден; иначе создайте новый экземпляр модели.

В пользовательском зрения обновления профиля:

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

Теперь, вместо того, чтобы создать новый профиль каждый раз - вы обновляете, если профиль для этого пользователя уже существует.

+0

Спасибо, что это работает! –

Смежные вопросы

 Смежные вопросы