请注意 - 这是my original question关于此主题的更新版本,但值得再次询问Django如何处理用户和身份验证。
我正在开发一个有两种不同用户的网站 - 让我们称他们为Customers
和Store Owners
。两者都在网站上注册,但功能却截然不同。 Customers
只有一个个人资料,可以在他们喜欢的商店中购物。 Store Owners
只有一个帐户,但可以访问多个商店,每个商店可以有多个Store Owners
。
模型的确切细节无关紧要,但这两类用户需要非常不同的字段。理想情况下,模型看起来像这样:
Customer
email (username)
password
name
address
time_zone
preferred_shipping
favorite_stores (many-to-many field)
...
Store Owner
email (username)
password
name
balance
stores_owned (many-to-many field on Stores)
stores_managed (many-to-many field on Stores)
...
最初,当Django的自定义用户支持不佳时,我有一个UserProfile
类,其中包含一些OneToOne
User
的其他字段,然后是Customer
和{在StoreOwner
上OneToOne
的{1}}类。这不是很好。
鉴于Django 1.5 / 1.6的变化,我试图想出最好的结构方法。现在,我有以下内容:
UserProfile
但是因为会有两种类型的用户,我无法将class CustomerUser(AbstractBaseUser):
...
class StoreOwnerUser(AbstractBaseUser):
...
设置为只有其中一种。
最好的结构方法是什么,以便我可以让两个不同类型的用户拥有不同的字段,而不会在用户身份验证,用户创建或管理员方面遇到任何问题?
此外,我如何能够从登录单独判断此用户是AUTH_USER_MODEL
还是CustomerUser
?
答案 0 :(得分:5)
您的用户类型似乎有一些常见功能和不常见的功能。如果您的用户类型中存在Django默认用户模型不支持的常用功能,则应直接对其进行子类化。
为您的用户类型添加额外的,不常见的功能最好不要通过子类化,而是使用配置文件。我的理由是因为您对这些用户类型的身份验证没有根本改变,但有关用户的详细信息取决于用户的类型。为了适应这种情况,您可以创建一个包含这些详细信息的单独模型,并将您的User类引用为OneToOne / ForeignKey关系(取决于您的设计)。
您可以对用户创建过程进行修改,以确定应该是哪种用户类型,并将其关联的OneToOneField / ForeignKey(取决于您的设计)设置为适当的客户类型模型。
通过这种方式,您应该只有一个AUTH_USER_MODEL,并且您应该能够处理不同客户类型的详细信息。
答案 1 :(得分:3)
最好的结构方法是什么,这样才能有两个 不同类型的用户使用不同的字段,而不会导致任何问题 用户身份验证,用户创建或管理员的问题?
您实际上只有一种类型的用户。只是某些用户设置了特定属性而其他用户没有。考虑一下django有“用户”和“管理员”。它们是相同模型的实例,但具有不同的属性和权限。
你应该同样接近它。为整个应用程序提供一个用户模型。您可以在自定义用户类中设置属性/方法,以标识此用户设置的标志(这将决定用户的“类型”)。
此外,我如何能够从登录单独判断此用户是否是
CustomerUser
或StoreOwnerUser
?
你可以使用user_passes_test
装饰器,它接受一个函数名称的参数,并且只在函数返回真值时处理视图。
答案 2 :(得分:1)
创建两个名为CustomerUser的子类和扩展BaseUser的StoreOwnerUser
from django.db import models
from django.contrib.auth.models import AbstractUser
class BaseUser(AbstractUser):
# all the common fields go here, for example:
email = models.EmailField(max_length=10,unique=True)
name = models.CharField(max_length=120)
class StoreOwnerUser(BaseUser):
# All Store Owner specific attribute goes here
balance = models.some_balance_field()
stores_owned = models.some_stores_owned_field()
class Meta:
verbose_name = 'Store Owner'
class CustomerUser(BaseUser):
# All Customer specific attribute goes here
customer_id = models.CharField(max_length=30, unique=True)
address = models.some_address
time_zone = models.something...
...
class Meta:
verbose_name = 'Customer'