我正在使用Python(3.7)和Django(2.2)开发一个项目,在其中我必须以以下方式实现多种类型的用户:
此外,我还需要使用email
作为登录/身份验证的username
字段。
[我正在尝试使用的策略是构建一个自User
继承的AbstractBaseUser
的自定义基本模型,并且还创建了一个自定义User Manager
以使email
成为username
,但它不起作用。] >
这是我完整的模型代码:
class UserManager(BaseUserManager): def _create_user(self, email, password, is_staff, is_superuser, **extra_fields): if not email: raise ValueError('Users must have an email address') now = timezone.now() email = self.normalize_email(email) user = self.model( email=email, is_staff=is_staff, is_active=True, is_superuser=is_superuser, last_login=now, date_joined=now, **extra_fields ) user.set_password(password) user.save(using=self._db) return user def create_user(self, email=None, password=None, **extra_fields): return self._create_user(email, password, False, False, **extra_fields) def create_superuser(self, email, password, **extra_fields): user = self._create_user(email, password, True, True, **extra_fields) user.save(using=self._db) return user def generate_cid(): customer_number = "".join([random.choice(string.digits) for i in range(10)]) return customer_number class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(max_length=255, unique=True) is_personal_above_18 = models.BooleanField(default=False) is_personal_below_18 = models.BooleanField(default=False) is_parent = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) is_active = models.BooleanField(default=True) last_login = models.DateTimeField(null=True, blank=True) date_joined = models.DateTimeField(auto_now_add=True) USERNAME_FIELD = 'email' EMAIL_FIELD = 'email' REQUIRED_FIELDS = [] objects = UserManager() def get_absolute_url(self): return "/users/%i/" % self.pk def get_email(self): return self.email class PersonalAccountAbove18(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='profile') customer_id = models.BigIntegerField(default=generate_cid) class PersonalAccountBelow18(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='profile') customer_id = models.BigIntegerField(blank=False) class ParentAccount(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name='profile') customer_id = models.BigIntegerField(default=generate_cid)
我对我的方法感到困惑,甚至当我以
makemigrations
身份运行时,它也返回错误:
users.User.user_permissions :(字段E304)“ User.user_permissions”的反向访问器与“ User.user_permissions”的反向访问器冲突。提示:在“ User.user_permissions”或“ User.user_permissions”的定义中添加或更改related_name参数。
更新:
我从子模型中删除了PermissionMixin
和related_name
属性,并且迁移现在正在运行,但仍需要username
而不是
[我正在使用Python(3.7)和Django(2.2)开发一个项目,在该项目中,我必须实现多种类型的用户:个人帐户-18岁以下的个人帐户-18岁以上的父母帐户的教练...
对于使用电子邮件作为登录名,我建议使用django-allauth
软件包。它可以解决所有繁重的工作,您可以使用它通过电子邮件(而不是用户名)登录。文森特(Will Vincent)对此有撰写,请访问:
https://wsvincent.com/django-allauth-tutorial-custom-user-model/
makemigrations
中的错误以及以后(除去PermissionsMixin
之后)要求使用username
而非email
进行身份验证的提示是,您尚未将自定义模型设置为default