首先让我说我从未使用过任何有很多用户表的系统(无论是否是 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'。您可能还需要不时清除悬空配置文件,因为使用上述属性您可以在保存用户对象之前创建配置文件。
最后,有许多替代方法可以处理多种用户类型,每种类型都有其权衡,这是一个品味问题 - 但恕我直言,在多个模型中传播用户名和密码是一个坏主意。