【问题标题】:Python - Multiple user types implementation in Django 2.2Python - Django 2.2 中的多用户类型实现
【发布时间】:2019-11-26 08:25:07
【问题描述】:

我正在使用 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,他将需要提供他的Parent帐户的customer_id .

【问题讨论】:

  • BaseUser 继承时,为什么需要一对一字段?
  • 是一个错误,刚刚删除。

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


【解决方案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)
    
  • 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_superusergroupsuser_permissions)和相关逻辑,你还想继承PermissionsMixindjango.contrib.auth.models.PermissionsMixin):

    class BaseUser(AbstractBaseUser, PermissionsMixin):
        ...
    
  • 您还需要创建自定义模型管理器来更新 create_user/create_superuser 方法以使用 email 字段而不是 username 字段来创建用户。您可以从here 获得灵感。

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

【讨论】:

  • 感谢您的回答,我修复了子模型中的一些问题,customer_id 将是我将不同帐户相互连接的关键,例如如果孩子想创建一个帐户他将需要其父帐户的customer_id。你能给我任何资源来了解组和权限吗?
  • @AbdulRehman 从官方文档开始:docs.djangoproject.com/en/2.2/topics/auth/default/#groups
  • 当然可以,但我仍然有与此问题相关的问题。
  • @AbdulRehman 如果您觉得提出新问题会更好,请这样做。这里不赞成将多个问题放在一个问题中,所以请考虑一下。另外,如果您觉得我的回答没有涵盖您最初的疑问,请说出来;如果您有一个清晰简洁的问题,我很乐意为您提供进一步的帮助。我不想要你的支持,如果你清楚自己想要什么,我想帮助你。谢谢。
  • 这是新问题:stackoverflow.com/q/59069679/7644562 请看一下!
猜你喜欢
  • 2012-11-21
  • 2020-07-17
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 2014-02-06
  • 2015-01-29
  • 1970-01-01
相关资源
最近更新 更多