Python-Django 2.2中的多种用户类型实现

时间:2019-11-26 08:25:07

标签: python django python-3.x django-models django-forms

我正在使用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帐户中的一个。

1 个答案:

答案 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_idid),因此不需要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_cidis_superusergroups)和user_permissions模型中的关联逻辑,您还想继承来自BaseUserPermissionsMixin):

    django.contrib.auth.models.PermissionsMixin
  • 您还想创建一个自定义模型管理器来更新class BaseUser(AbstractBaseUser, PermissionsMixin): ... / create_user方法,以使用create_superuser字段代替email来创建用户领域。您可以从here中汲取灵感。

  • username模型重命名为UserBase是有意义的,以保持与Django过程/方法的一致性。

相关问题