我正在使用Python(3.7(和Django(2.2(进行一个项目,其中我必须实现四种类型的用户作为(1): Personal - Below 18 (2): Personal 18 or Above (3): Coach (4): Parent
,每个用户将共享一些基本字段,如First & Lat name, Email, Gender, Account type
但也将具有不同的权限,仪表板和功能,并且需要提供不同的注册表单,但一个登录表单。除此之外,我还需要使用Email
作为该项目的用户名。 什么是好的和可扩展的方法?任何资源或教程链接将不胜感激。 在这种情况下,我该如何利用django-allauth
?
以下是我的想法来实现这一点:
class BaseUser(AbstractBaseUser):
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)
USERNAME_FIELD = 'email'
def __str__(self):
return self.email + '/s account'
class PersonalAccountAbove18(BaseUser):
customer_id = models.BigIntegerField(default=generate_cid())
class PersonalAccountBelow18(BaseUser):
customer_id = models.BigIntegerField(blank=False)
class ParentAccount(BaseUser):
customer_id = models.BigIntegerField(default=generate_cid())
在每个模型中使用customer_id
的原因是,稍后我们需要连接不同的帐户,例如,如果有人想要创建一个 aspERSONAL - BELOW 18
他将需要提供他的Parent
帐户的customer_id
。
看看在BaseUser
模型中创建一个额外的字段来分隔帐户是否有效,但如果它看起来很复杂并且您想为每个帐户容纳一大堆自定义,那么为每个帐户创建一个单独的模型确实有意义。
如果后者是正确的,那么理论上,您应该使用单个User
模型,并保持从单独帐户到此模型的一对一。在User
模型中保留通用逻辑,同时保留特定于帐户模型的逻辑。
您编写的实现存在一些问题:
您的所有单个
*Account*
模型都继承自BaseUser
,并且与它一对一;这将在字段映射和检索方面造成各种破坏。BaseUser
是一个具体的模型,因此仅保留一对一的关系并从django.db.models.Model
继承,例如:class PersonalAccountAbove18(Model): user = models.OneToOneField(BaseUser, on_delete=models.CASCADE, primary_key=True)
coutomer_id
字段不是必需的,因为 Django 有一个唯一标识每一行的id
(AutoField
(,所以你可以利用它。此外,由于您没有在customer_id
字段上使用primary_key
因此无论如何都会创建id
字段。如果由于某种原因您需要BigIntegerField
(因为从长远来看具有可伸缩性(,您最好将其设为primary_key
,这样就不会创建id
字段(假设generate_cid()
每次都返回表的唯一值(:class PersonalAccountAbove18(Model): user = models.OneToOneField(BaseUser, on_delete=models.CASCADE, primary_key=True) customer_id = models.BigIntegerField(primary_key=True, default=generate_cid)
您设置了
default=generate_cid()
这意味着所有实例的default
与定义时设置的默认值相同。您需要放弃对generate_cid
的呼叫(即default=generate_cid
( 就像我在上一点中所做的那样,在实例实际需要字段值时进行评估如果要在
BaseUser
模型中使用与权限相关的字段(is_superuser
、groups
、user_permissions
(和相关逻辑,还需要从PermissionsMixin
(django.contrib.auth.models.PermissionsMixin
(继承:class BaseUser(AbstractBaseUser, PermissionsMixin): ...
您还需要创建自定义模型管理器以更新
create_user
/create_superuser
方法,以使用email
字段而不是username
字段创建用户。你可以从这里获得灵感。
将UserBase
模型重命名为User
以保持与 Django 过程/方法的一致性是有意义的。