gpt4 book ai didi

python - Django自定义身份验证模型注册表单返回唯一用户名错误

转载 作者:行者123 更新时间:2023-12-01 08:46:20 24 4
gpt4 key购买 nike

我有自己的用户模型,称为 User。我有一个用户注册表单,它返回以下错误:

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 迁移过来,并且在运行前者时没有遇到任何问题。

最佳答案

我认为,与其从 AbstractUser 子类化,不如从 AbstractBaseUser 子类化更好。因为 AbstractUserusername 字段并且默认是唯一的,但是 AbstractBaseUser 只有 passwordlast_login 字段,它提供了用户模型的核心实现。还有一个缺点,例如 AbstarctBaseUser 没有 is_stafffirst_namelast_nameis_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')

请查看here有关使用自定义用户模型的更多详细信息。您也可以检查这个SO answer关于 AbstractBaseUserAbstractUser 之间的差异。

或者您仍然可以使用AbstractUser,但需要覆盖用户名字段

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

关于python - Django自定义身份验证模型注册表单返回唯一用户名错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53291930/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com