Ошибка при регистрации пользовательского пользователя в Django - PullRequest
1 голос
/ 01 апреля 2019

Когда я хочу зарегистрировать нового пользователя в Django, я получаю следующее предупреждение:

UNIQUE constraint failed: polls_usuario.matriculaUsuario

Когда я редактирую реестр, как администратором, так и в главном представлении, эта ошибка не возникает.Эта ошибка возникает только при создании нового пользователя.Когда я создаю пользователя с помощью регистра просмотра, создается пользователь с регистрацией по умолчанию.Когда я пытаюсь создать администратором, пользователь даже не создается.Что может происходить?

views.py

def registrar(request):
    if request.method == 'POST':
        form = SignUpForm(request.POST)
        usuario_form = UsuarioForm(request.POST)
        if form.is_valid() and usuario_form.is_valid():
            user = form.save(commit=False)
            user.refresh_from_db()  # load the profile instance created by the signal
            user.usuario.matriculaUsuario = form.cleaned_data.get('matriculaUsuario')
            usuario_form.save()
            user.save()
            raw_password = form.cleaned_data.get('password1')
            user = authenticate(username=user.username, password=raw_password)
            login(request,user)
            return render(request, 'polls/index.html', user)
            #return HttpResponseRedirect(reverse('/')) 
            #return redirect('/')
    else:
        form = SignUpForm()
        usuario_form = UsuarioForm()
    return render(request, 'polls/registrar.html', {'form': form , 'usuario_form':usuario_form})

forms.py

class UsuarioForm(forms.ModelForm):
    class Meta:
        model = Usuario
        fields = ('matriculaUsuario',)

class SignUpForm(UserCreationForm):
    first_name = forms.CharField(label='Primeiro Nome',max_length=30, required=False, help_text='Opcional.')
    last_name = forms.CharField(label='Último Nome',max_length=30, required=False, help_text='Opcional.')
    email = forms.EmailField(label='E-mail',max_length=254, help_text='Informe o seu e-mail (Requerido)')   
    username = forms.CharField(label='Nome de usuário', min_length=4, max_length=150)
    password1 = forms.CharField(label='Senha', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Confirmação da senha', widget=forms.PasswordInput)

    matriculaUsuario = forms.CharField(label='Matrícula',max_length=12,validators=[ validators.RegexValidator(re.compile('^[0-9]{12}$'), _('Digite uma matrícula válida'), _('invalid'))])

    class Meta:
        model = User
        fields = ['first_name', 'last_name','username','matriculaUsuario','email','password1', 'password2',] 
    def clean_username(self):
        username = self.cleaned_data['username'].lower()
        r = User.objects.filter(username=username)
        if r.count():
            raise  ValidationError("Nome de usuário já cadastrado")
        return username

    def clean_email(self):
        email = self.cleaned_data['email'].lower()
        r = User.objects.filter(email=email)
        if r.count():
            raise  ValidationError("E-mail já cadastrado")
        return email

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')

        if password1 and password2 and password1 != password2:
            raise ValidationError("Senhas não conferem")

        return password2

    def save(self, commit=True):
        user = User.objects.create_user(
            self.cleaned_data['username'],
            self.cleaned_data['email'],
            self.cleaned_data['password1']
        )
        return user
class EditProfileForm(forms.ModelForm):
    first_name = forms.CharField(label='Nome')
    last_name = forms.CharField(label='Sobrenome')
    username = forms.CharField(min_length=4, max_length=150,help_text=("Insira um novo nome de usuário"), label='Nome de usuário')
    email = forms.EmailField(label='E-mail')
    matriculaUsuario = forms.CharField(label='Matrícula', max_length=12,validators=[ validators.RegexValidator(re.compile('^[0-9]{12}$'), _('Digite uma matrícula válida'), _('invalid'))])
    class Meta:
        model = User
        fields = ['first_name', 'last_name','username','matriculaUsuario','email']

models.py

class Usuario(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,null=True)
    matriculaUsuario = models.CharField(default='000000000000',max_length=12,primary_key=True,null=False,help_text=_('São requeridos os 12 dígitos referentes à sua matrícula'), validators=[ validators.RegexValidator(re.compile('^[0-9]{12}$'), _('Digite uma matrícula válida'), _('invalid'))])
    def __str__(self):
        return self.user.username
    @receiver(post_save, sender=User)
def update_user_usuario(sender, instance, created, **kwargs):
    if created:
        Usuario.objects.create(user=instance)
    instance.usuario.save()

@receiver(post_save, sender=User)
def create_user_usuario(sender, instance, created, **kwargs):
    if created:
        Usuario.objects.create(user=instance)
post_save.connect(create_user_usuario,sender=User)
@receiver(post_save, sender=User)
def save_user_usuario(sender, instance, created,**kwargs):
    if created:
        instance.usuario.save()

1 Ответ

0 голосов
/ 01 апреля 2019

В вашем models.py вы устанавливаете matriculaUsuario как primary_key:

class Usuario(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,null=True)
    matriculaUsuario = models.CharField(default='000000000000',max_length=12,primary_key=True,null=False,help_text=_('São requeridos os 12 dígitos referentes à sua matrícula'), validators=[ validators.RegexValidator(re.compile('^[0-9]{12}$'), _('Digite uma matrícula válida'), _('invalid'))]) # you set this as primary key

Вы также установите для него значение по умолчанию = '000000000000'. Это плохо, потому что когда вы создаете нового пользователя и форма сохраняется, поле каждый раз получает одно и то же значение ('000000000000'). Это невозможно, так как вы установили primary_key = True. Первичный ключ - это уникальный идентификатор объекта, поэтому он должен быть уникальным.

primary_key = True означает, что null = False, а уникальный = True. На объекте допускается только один первичный ключ.

ссылка: https://django.readthedocs.io/en/2.1.x/ref/models/fields.html

Рассмотрите возможность использования AutoField, которое будет автоматически увеличивать pk при создании объекта:

matriculaUsuario = models.AutoField(primary_key=True)

Или еще одним хорошим вариантом является UUIDField, который подходит для долгосрочной, более крупной базы данных, а также для того, чтобы злоумышленникам было трудно угадать pk объекта.

matriculaUsuario = models.UUIDField(primary_key=True, unique=True, default=uuid.uuid4, editable=False)

Кроме того, я не думаю, что вы должны разрешать пользователям редактировать их matricualUsuario в форме EditProfile, поскольку это создаст проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...