Не удается заставить OneToOneField работать с формами - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь добавить больше полей в модель пользователя по умолчанию в Django.Я использую метод OneToOneField.Я хочу создать страницу регистрации, которая позволяет пользователю заполнять имя пользователя, пароль, адрес электронной почты и другие поля, которые я добавлю в отдельную модель профиля.Я использовал некоторые фрагменты кода, которые нашел, и попытался заставить его работать.Тем не менее, я продолжаю получать ошибку IntegrityError at /account/signup/ UNIQUE constraint failed: accounts_profile.user_id.Я думаю, что проблема в том, что именно тогда, когда создается пользователь, также создается профиль.Затем, когда создается новый профиль с использованием первичного ключа пользователя, он выдает ошибку, поскольку профиль для этого первичного ключа уже существует.Может кто-нибудь показать мне правильный способ сделать это?

Вот весь соответствующий код:

models.py:

from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    GENDER_CHOICES = (
        ('MALE', 'Male'),
        ('FEMALE', 'Female')
    )
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    middle_name = models.CharField(max_length=30, blank=True, default='')
    prefix = models.CharField(max_length=6, blank=True, default='')
    suffix = models.CharField(max_length=10, blank=True, default='')

    def __str__(self):
        return self.user.username


@receiver(post_save, sender=User)
def create_or_update_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)
    instance.profile.save()

forms.py

from django import forms
from django.forms import ModelForm
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

from .models import Profile


class RegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = (
            'username',
            'first_name',
            'last_name',
            'email',
            'password1',
            'password2',
        )

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']

        if commit:
            user.save()

        return user


class ProfileForm(ModelForm):

    class Meta:
        model = Profile
        fields = (
            'middle_name',
            'prefix',
            'suffix',
        )

    def save(self, commit=True):
        profile = super(ProfileForm, self).save(commit=False)
        profile.middle_name = self.cleaned_data['middle_name']
        profile.prefix = self.cleaned_data['prefix']
        profile.suffix = self.cleaned_data['suffix']

        if commit:
            profile.save()

        return profile

views.py

...
def signup_view(request):
    if request.method == 'POST':
        register = RegistrationForm(request.POST, prefix='register')
        userprofile = ProfileForm(request.POST, prefix='profile')
        print(register.is_valid())
        print(userprofile.is_valid())
        if register.is_valid() * userprofile.is_valid():
            user = register.save()
            profile = userprofile.save(commit=False)
            print(user)
            profile.user = user
            profile.save()

            return HttpResponse('congrats')
        else:
            return HttpResponse('errors')
    else:
        userform = RegistrationForm(prefix='register')
        userprofileform = ProfileForm(prefix='profile')
        return render(request, 'accounts/signup.html', {'userform': userform,
                                                        'userprofileform': userprofileform})
...