Форма регистрации пользовательской модели Django возвращает ошибку уникального имени пользователя - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть своя собственная пользовательская модель под названием Пользователь.У меня есть форма регистрации пользователя, которая возвращает эту ошибку ниже:

duplicate key value violates unique constraint "users_user_username_06e46fe6_uniq"
DETAIL:  Key (username)=() already exists.

Может ли быть, что модель пользователя сохраняется дважды?

Это моя форма:

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

        @transaction.atomic
        def save(self):
            user = super().save(commit=False)
            user.is_fighter = True
            user.is_active = False
            user.save()
        return user

Это мой взгляд:

class FighterSignUpView(CreateView):

    model = User
    form_class = FighterSignUpForm
    template_name = 'registration/user_signup.html'

    def get_context_data(self, **kwargs):
        kwargs['user_type'] = 'example'
        return super().get_context_data(**kwargs)

    def form_valid(self, form):
        user = form.save()

Это пользовательская модель пользователя:

        class UserManager(BaseUserManager):

            use_in_migrations = True

            def _create_user(self, email, password, **extra_fields):
                if not email:
                    raise ValueError('The given email must be set')
                email = self.normalize_email(email)
                user = self.model(email=email, **extra_fields)
                user.set_password(password)
                user.save(using=self._db)
                return user

            def create_user(self, email, password=None, **extra_fields):
                extra_fields.setdefault('is_staff', False)
                extra_fields.setdefault('is_superuser', False)
                return self._create_user(email, password, **extra_fields)

            def create_superuser(self, email, password, **extra_fields):
                extra_fields.setdefault('is_staff', True)
                extra_fields.setdefault('is_superuser', True)

                if extra_fields.get('is_staff') is not True:
                    raise ValueError('Superuser must have is_staff=True.')
                if extra_fields.get('is_superuser') is not True:
                    raise ValueError('Superuser must have is_superuser=True.')

                return self._create_user(email, password, **extra_fields)

        class User(AbstractUser):
            email = models.EmailField(_('Email'), unique=True)

            USERNAME_FIELD = 'email'
            REQUIRED_FIELDS = []

            is_type1 = models.BooleanField(default=False, verbose_name="type1")
            is_type2 = models.BooleanField(default=False, verbose_name="type2")
            is_type3 = models.BooleanField(default=False, verbose_name="type")
            is_confirmed = models.BooleanField(default=False, verbose_name="Has Confirmed Email")

            objects = UserManager()

Я только недавно переместил свою базу данных из SQlite3, и у меня никогда не возникало этой проблемы, когдапод управлением бывшего.

1 Ответ

0 голосов
/ 14 ноября 2018

Вместо того, чтобы создавать подклассы из AbstractUser, я думаю, что лучше подклассы из AbstractBaseUser.Потому что AbstractUser имеет поле username и уникально по умолчанию, а AbstractBaseUser имеет только поля password и last_login, и оно обеспечивает базовую реализацию модели User.Есть и обратная сторона, например, AbstarctBaseUser не имеет полей is_staff, first_name, last_name, is_superuser и поля, связанные с разрешениями, также отсутствуют.Так что лучше, если вы используете это так:

class User(AbstractBaseUser, PermissionsMixin):
    first_name = models.CharField(_('first name'), max_length=255, blank=True)
    last_name = models.CharField(_('last name'), max_length=255, blank=True)
    email = models.EmailField(_('email address'), blank=True, max_length=50)
    is_staff = models.BooleanField(_('staff status'), default=False,
                                help_text=_('Designates whether the user'
                                            ' can log into this admin '
                                            'site.'))
    is_active = models.BooleanField(_('active'), default=True,
                                    help_text=_('Designates whether '
                                                'this user should be '
                                                ' treated as '
                                                'active. Unselect this '
                                                ' instead of '
                                                ' deleting accounts.'))
    objects = UserManager()
    # rest of your fields

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['email']

    def get_short_name(self):
        return self.first_name

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')

Пожалуйста, проверьте здесь об использовании пользовательской модели пользователя для получения более подробной информации.Также вы можете проверить этот SO ответ о различиях между AbstractBaseUser и AbstractUser .

или , которые вы все еще можете использовать AbstractUser но нужно переопределить username поле

class User(AbstractBaseUser, PermissionsMixin):
     username = models.CharField(_('username'), max_length=255, blank=True, unique=False)
...
# rest of your fields
...