我正在使用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
的原因是因为以后我们需要连接不同的帐户,例如,如果某人想要创建一个pERSONAL - BELOW 18
的帐户,则他需要提供一个customer_id
Parent
帐户中的一个。
答案 0 :(得分:1)
看看是否在BaseUser
模型中创建了一个额外的字段来分隔帐户,但是如果它看起来很复杂并且您想为每个帐户提供一整套定制,那么确实有必要为每个。
如果后者是正确的,那么从理论上讲,您应该使用单个User
模型,并保持单独帐户与该模型之间的一对一关系。并将通用逻辑保留在User
模型中,同时将特定于帐户模型的逻辑保留在其中。
您编写的实现存在一些问题:
您所有的*Account*
模型都继承自BaseUser
,并且一对一。这将对现场映射和检索造成各种各样的破坏。 BaseUser
是一个具体模型,因此只能保持一对一关系并从django.db.models.Model
继承,例如:
class PersonalAccountAbove18(Model):
user = models.OneToOneField(BaseUser, on_delete=models.CASCADE, primary_key=True)
由于Django具有唯一标识每一行的coutomer_id
(id
),因此不需要AutoField
字段,因此您可以利用它。同样,由于您没有在primary_key
字段上使用customer_id
,因此无论如何都会创建id
字段。如果出于某种原因需要使用BigIntegerField
(从长远来看,由于可伸缩性),最好将primary_key
设置为id
字段(假设{{1} }每次都返回表的唯一值):
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
,is_superuser
,groups
)和user_permissions
模型中的关联逻辑,您还想继承来自BaseUser
(PermissionsMixin
):
django.contrib.auth.models.PermissionsMixin
您还想创建一个自定义模型管理器来更新class BaseUser(AbstractBaseUser, PermissionsMixin):
...
/ create_user
方法,以使用create_superuser
字段代替email
来创建用户领域。您可以从here中汲取灵感。
将username
模型重命名为UserBase
是有意义的,以保持与Django过程/方法的一致性。