繁体   English   中英

如何使用具有非常不同属性的两种类型的用户设置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管理员,用户身份验证等。

从概念上讲,该网站有两种用户:学生和企业。 这两种类型的用户具有完全不同的权限和存储的信息。 情况就是这样,在网站的原始结构中,我们建立了如下数据模型:

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>
    ...

这对我们来说非常有效,我们在Users表中提供了简单的用户信息,然后在Students and Businesses表中提供了更详细的信息。 获取用户的完整个人资料需要此伪代码:

def get_user_profile(id):
    if Users(id=id).Business_or_Student = 'B':
        return Businesses(id=id)
    else:
        return Students(id=id)

在移动过程中,我发现Django的内置User对象具有非常有限的功能,我不得不使用我创建的UserProfile类扩展它,然后有额外的StudentBusiness表。 鉴于我在Django管理员中所做的所有补丁,并且对Django模型相对不熟悉,因为我总是采用不同的方式,我不确定这是否是最好的方法,或者我应该只需将企业和学生的所有信息粘贴在UserProfile表中,然后将两者区分为不同的组,或者甚至在内置的User对象中有一些方法可以完成这一切。

由于企业和学生也有不同的界面,我正在认真考虑在我的Django项目中将两者设置为不同的应用程序,从而完全分离他们的视图,模型等。 这看起来像是这样的:

MyProject/
    MyProject/ (project folder, Django 1.4)
    mainsite/
    students/
    businesses/

我最关心的一个问题是Django Admin。 在扩展User ,我必须添加以下代码:

class UserProfileInline(admin.StackedInline):
    model = UserProfile
    can_delete = False
    verbose_name_plural = 'profile'

class UserAdmin(UserAdmin):
    inlines = (UserProfileInline, )

但是,当User被拉起时,我希望用户的业务或学生方面的信息显示在Django管理员中,但是模型的ForeignKey部分在StudentBusiness模型中,因为每个Student / Business都有User但每个User只有一个Student 一个Business对象与之相关联。 我不知道如何为Admin添加条件内联。

问题:鉴于这种结构和这些问题,设置此站点的最佳方式是什么,尤其是数据模型?

这不是一个完整的解决方案,但它会让您了解从哪里开始。

  • mainsite创建UserProfile模型。 这将保留两种类型用户的任何公共属性。 使用OneToOne(...)字段将其与User模型相关联。
  • 在每个应用程序(学生/企业), BusinessStudent创建另外两个模型,这些模型与UserProfile具有OneToOne关系(或从UserProfile继承)。 这将包含特定于该类型用户的属性。 文档: 多重继承 / OneToOne关系
  • 可以UserProfile添加一个字段,以区分它是商家还是学生的个人资料。

然后,对于内容管理:

  • 定义save()函数以自动检查冲突(例如,有一个与UserProfile关联的BusinessStudent条目,或者没有条目)。
  • 必要时定义__unicode__()表示。

我希望我能理解你的问题...也许这可行吗? 您创建一个抽象的CommonInfo类,它继承到不同的子类(学生和企业)

class CommonUser(models.Model):      
    user = models.OneToOne(User)
    <any other common fields>

    class Meta:
        abstract = True


class Student(CommonUser):
    <whatever>

class Business(CommonUser):
    <whatever>

在这种情况下,模型将在DB中创建,每个表中都有基类字段。 因此,当您与学生一起工作时,您可以运行

students = Students.objects.get.all() 

让所有学生都参与其中。

然后为每个学生做:

for student in students:
    print student.user.username

对于Business对象也是如此。

让学生使用用户:

student = Student.objects.get(user=id)

用户名将是唯一的,因此在创建新的学生或企业时,如果正在保存现有用户名,则会引发异常。

忘了添加链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM