gjb*_*gjb 37 django django-models django-1.5
使用Django 1.5的新可配置用户模型功能实现多种用户类型的推荐方法是什么?
我想有两种用户类型:私人用户和交易用户,每个用户都有自己的必填字段集.
我可以通过两种方式来实现这一点:
class BaseUser(AbstractBaseUser):
email = models.EmailField(max_length=254, unique=True)
# ...
class PrivateUser(BaseUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
# ...
class TradeUser(BaseUser):
company_name = models.CharField(max_length=100)
# ...
Run Code Online (Sandbox Code Playgroud)
将多表继承与可配置用户模型结合使用是否有任何问题?
class User(AbstractBaseUser):
email = models.EmailField(max_length=254, unique=True)
user_type = models.CharField(max_length=30, choices={
'P': 'Private',
'T': 'Trade',
})
first_name = models.CharField(max_length=30, blank=True)
last_name = models.CharField(max_length=30, blank=True)
company_name = models.CharField(max_length=100, blank=True)
# ...
Run Code Online (Sandbox Code Playgroud)
此方法需要一些依赖于条件验证user_type.
哪种方法最适合我的用例?或许有更好的方法来实现这一目标?
此外,在案例编号1中,如何过滤用户?
谢谢.
bor*_*ges 29
警告:Django 1.5非常新,人们仍在调查其新功能.基于最近的研究回答这个问题,我的回答只不过是我的意见.
两种方式都是实现结果的有效方式,有其优点和缺点.
让我们从:
第二种选择
AbstractBaseUser顾名思义,它是一个抽象模型,没有特定的表格您需要使用使用额外字段的模型检查user_type以进行任何迭代:
def foo():
if user.user_type == 'Private':
# ...
else:
# ...
Run Code Online (Sandbox Code Playgroud)生成的SQL大致如下:
CREATE TABLE "myapp_user" (
"id" integer NOT NULL PRIMARY KEY,
"password" varchar(128) NOT NULL,
"last_login" datetime NOT NULL,
"email" varchar(254) NOT NULL UNIQUE,
"user_type" varchar(30) NOT NULL,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL,
"company_name" varchar(100) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
第一种选择
BaseUserManager为每个子项实现 create_userBaseUser.objects.all()*访问子类生成的SQL大致如下:
CREATE TABLE "myapp_baseuser" (
"id" integer NOT NULL PRIMARY KEY,
"password" varchar(128) NOT NULL,
"last_login" datetime NOT NULL,
"email" varchar(254) NOT NULL UNIQUE
);
CREATE TABLE "myapp_privateuser" (
"baseuser_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_baseuser" ("id"),
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
CREATE TABLE "myapp_tradeuser" (
"baseuser_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "myapp_baseuser" ("id"),
"company_name" varchar(100) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
*想象一下以下情况:
>>> BaseUser.objects.create_user('baseuser@users.com', password='baseuser')
>>> PrivateUser.objects.create_user('privateuser@users.com', password='privateuser', first_name='His', last_name='Name')
>>> TradeUser.objects.create_user('tradeuser@users.com', password='tradeuser', company_name='Tech Inc.')
>>> BaseUser.objects.all()
[<BaseUser: baseuser@users.com>, <BaseUser: privateuser@users.com>, <BaseUser: tradeuser@users.com>]
>>> PrivateUser.objects.all()
[<PrivateUser: privateuser@users.com>]
>>> TradeUser.objects.all()
[<TradeUser: tradeuser@users.com>]
Run Code Online (Sandbox Code Playgroud)
因此,您无法通过使用直接检索子类实例BaseUser.objects.all().杰夫有一篇很棒的博客文章,更好地解释了如何从BaseUser孩子们那里完成"自动垂头丧气" .
也就是说,您应该考虑每种方法的优缺点及其对项目的影响.当涉及的逻辑很小时(如在所描述的示例中),两种方法都是有效的.但在更复杂的情况下,一种方法可能比另一种方法更好.我会选择多模型选项,因为它更具可扩展性.
| 归档时间: |
|
| 查看次数: |
9098 次 |
| 最近记录: |