如何使用具有非常不同属性的两种类型的用户来设置Django模型 [英] How to set up Django models with two types of users with very different attributes
问题描述
注意:自从再次提出这个问题,因为自1.5版以来Django的用户模型更新。
我正在重建和制作改进已经存在的Django站点,并将其从Webfaction迁移到Heroku,以及从Amazon的SimpleDB迁移到Heroku Postgres(尽管在开发过程中在Sqllite3上进行测试)。我正在做的很多工作是转移到使用内置的Django功能,如Django管理员,用户身份验证等。
从概念上说,该网站有两个用户种类:学生和企业。这两种类型的用户具有与它们完全不同的权限和信息。在网站的原始结构中,我们设置了以下数据模型:
用户
ID(primary_key)
Business_or_Student('B'如果商业,'S'如果学生)
电子邮件(唯一)
密码(散列,显然)
...
学生
ID(用户上的外键)
<更多信息>
...
企业
ID(用户上的外键)
<更多信息>
...
这对我们来说非常好,我们有裸骨Users表中的用户信息,以及学生和企业表中的更多详细信息。获取用户的完整配置文件需要这个伪代码:
def get_user_profile(id):
。这将保存两种类型的用户的任何常见属性。将其与
如果用户(id = id)id = id b)
$ b $ / code $ pre>
在移动过程中,我发现Django的内置
用户
对象具有非常有限的功能,我不得不使用我创建的UserProfile
类来扩展它,然后再增加学生
和业务
表。鉴于我在Django管理员中所做的全部修补,并且对Django的模型比较陌生,因为我总是这样做,我不知道这是否是最好的方法,或者我应该只需在UserProfile
表中的企业和学生的所有信息 中只是区分两者,或者甚至有一些方法这样做全部在内置的用户
对象中。
由于企业和学生也有不同的界面,我认真考虑将Django项目中的两个应用程序设置为不同的应用程序,并将其视图,模型等完全分开。这将看起来像:
MyProject /
MyProject /(项目文件夹,Django 1.4)
主站/
学生/
企业/
我最大的担忧之一是Django管理员在
用户
中,我必须添加以下代码:UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural ='profile'
class UserAdmin(UserAdmin):
inlines =(UserProfileInline,)
但是,我希望用户的业务或学生方面的信息当在
User
被拉起时,Django管理员中显示,但模型的ForeignKey
部分是在学生
和商业
模型,因为每个学生
/业务
有一个用户
,但每个用户
只有一个学生
或一个业务
对象连接。我不知道如何为管理员添加条件内联。
问题:鉴于此结构和这些问题,设置的最佳方法是什么这个网站,特别是数据模型?
解决方案这不是一个完整的解决方案,但它会给你一个想要从哪里开始。
- 在$ $ c $中创建一个
UserProfile
C> mainsite用户
模型与OneToOne(...)
字段相关。
业务
和学生
中创建两个模型, code> OneToOne 每个与 UserProfile
(或继承自 UserProfile
)的关系。这将保存特定于该类型用户的属性。文件:多重继承 / OneToOne关系 UserProfile
中添加一个字段来区分是商业还是学生的个人资料。然后,对于内容管理:
- 定义
save()
函数自动检查冲突(例如,有Business
和学生
之间的条目一个UserProfile
,或没有条目)。 - 定义
__ unicode __()
必要时的陈述。
Note: I've since asked this question again given the updates to Django's user model since version 1.5.
I'm rebuilding and making improvements to an already existing Django site and moving it over from Webfaction to Heroku, and from Amazon's SimpleDB to Heroku Postgres (though testing locally on Sqllite3 when developing). A lot of what I'm doing is moving over to use built-in Django functionality, like the Django admin, user authentication, etc.
Conceptually, the site has two kinds of users: Students and Businesses. The two types of users have completely different permissions and information stored about them. This is so much the case that in the original structure of the site, we set up the data model as follows:
Users
ID (primary_key)
Business_or_Student ('B' if business, 'S' if student)
email (unique)
password (hashed, obviously)
...
Students
ID (Foreignkey on Users)
<more information>
...
Businesses
ID (Foreignkey on Users)
<more information>
...
This worked pretty well for us, and we had the bare-bones user information in the Users table, and then any more detailed information in the Students and Businesses tables. Getting a user's full profile required something along this pseudocode:
def get_user_profile(id):
if Users(id=id).Business_or_Student = 'B':
return Businesses(id=id)
else:
return Students(id=id)
In moving over, I've found that Django's built-in User
object has pretty limited functionality, and I've had to extend it with a UserProfile
class I've created, and then had additional Student
and Business
tables. Given all of the patching I'm doing with this in the Django admin, and being relatively unfamiliar with Django models since I always did it differently, I'm not sure if this is the best way to go about it, or if I should just stick all of the information for businesses and students in the UserProfile
table and just differentiate the two with different groups, or if there's even some way to do this all in the built-in User
object.
Since businesses and students also have different interfaces, I'm seriously considering setting up the two as different apps within my Django project, and so separating their views, models, etc. entirely. That would look something like:
MyProject/
MyProject/ (project folder, Django 1.4)
mainsite/
students/
businesses/
One of my biggest concerns is with the Django Admin. In extending User
, I already had to add the following code:
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'profile'
class UserAdmin(UserAdmin):
inlines = (UserProfileInline, )
However, I would like the information for the Business or Student aspects of the user to show up in the Django admin when that User
is pulled up, but the ForeignKey
part of the model is in the Student
and Business
model since every Student
/Business
has a User
but every User
has only one Student
or one Business
object connected with it. I'm not sure how to add a conditional Inline for the Admin.
Question: Given this structure and these concerns, what is the best way to set up this site, particularly the data model?
This is not a complete solution, but it will give you an idea of where to start.
- Create a
UserProfile
model inmainsite
. This will hold any common attributes for both types of users. Relate it to theUser
model with aOneToOne(...)
field. - Create two more models in each app, (student/business),
Business
andStudent
, which haveOneToOne
relationships each withUserProfile
(or inherit fromUserProfile
). This will hold attributes specific to that type of users. Docs: Multitable inheritance / OneToOne Relationships - You may add a field in
UserProfile
to distinguish whether it is a business or student's profile.
Then, for content management:
- Define the
save()
functions to automatically check for conflicts (e.g. There is an entry for bothBusiness
andStudent
associated with aUserProfile
, or no entries). - Define the
__unicode__()
representations where necessary.
这篇关于如何使用具有非常不同属性的两种类型的用户来设置Django模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!