【问题标题】:Multiple Django apps used for multiple authentication role用于多个身份验证角色的多个 Django 应用程序
【发布时间】:2018-12-10 16:09:51
【问题描述】:

在后端使用 MySql。

有两个角色,客户和供应商。我必须为这两个角色使用自定义身份验证。 我已经生成了两个应用程序客户和供应商,我通过在客户应用程序中使用类 User(AbstractBaseUser): 模型成功覆盖了 Django 的 AUTH_USER_MODEL,该模型创建了表 customer_user,替换了默认情况下由 Django 提供的 auth_user 表。 custom auth_user_model for customer

现在同样我想在数据库中创建 vendor_user 表,并为供应商应用程序提供自定义身份验证。 我注意到默认情况下 Django 为单个项目提供单一身份验证模型。 如何为项目创建多个自定义身份验证模型?

【问题讨论】:

    标签: django django-models django-forms django-rest-framework


    【解决方案1】:

    首先让我说我从未使用过任何有很多用户表的系统(无论是否是 Django),每个用户角色一个。始终只有一个用户表在系统中的每个用户之间共享,无论他们扮演什么角色。当您经常看不到某些设置时,这意味着它不起作用,所以我的建议是:无论您选择什么策略,或者您的业务模型是什么,始终使用一个,并且只有一个 Django 模型来处理身份验证。

    如果您需要维护与用户相关的额外信息,您必须问自己这些特定信息是与所有用户相关还是仅与某些类型的用户相关。例如,“客户编号”可能仅与客户用户相关。在这种情况下,您最好通过一对一的关系添加配置文件模型。现在,如果额外信息与所有用户相关(例如,头像图像),最好的办法是直接向用户模型添加一个额外字段。

    您可能有一个“角色”字段并使用继承或一对一关系,以便将此基本用户模型链接到特定于配置文件的模型。我同时使用了继承和外键,我更喜欢外键而不是配置文件模型而不是模型继承(无论如何,模型继承都是使用一对一关系实现的,所以我宁愿明确说明)。

    你可以有这样的东西:

    class User(models.Model):
        ROLES = (
            ('customer', 'Customer'),
            ('vendor', 'Vendor'),
        )
        ...
        role = models.CharField(max_length=30, choices=ROLES)
        vendor_profile = models.OneToOneField(
                             VendorProfile, 
                             on_delete=models.CASCADE,
                             blank=True, null=True) 
        customer_profile = models.OneToOneField(
                             CustomerProfile, 
                             on_delete=models.CASCADE,
                             blank=True, null=True)
        ...
        @property
        def profile(self):
            if self.role == 'vendor':
                if not self.vendor_profile_id:
                    self.vendor_profile = VendorProfile.objects.create()
                    if self.pk:
                        self.save()
                return self.vendor_profile
            if not self.customer_profile_id:
                self.vendor_profile = CustomerProfile.objects.create()
                if self.pk:
                    self.save()
            return self.customer_profile
    

    但它不是完全透明的 - 例如,如果您必须根据特定角色模型字段过滤查询集,则必须根据用户角色使用 vendor_profile__foo='Bar'customer_profile__foo='Bar'。您可能还需要不时清除悬空配置文件,因为使用上述属性您可以在保存用户对象之前创建配置文件。

    最后,有许多替代方法可以处理多种用户类型,每种类型都有其权衡,这是一个品味问题 - 但恕我直言,在多个模型中传播用户名和密码是一个坏主意。

    【讨论】:

    • 谢谢保罗,这很有帮助。
    猜你喜欢
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2012-11-03
    • 2020-12-26
    相关资源
    最近更新 更多