2012-03-10 101 views
19

最初,我开始了我的用户配置是这样的:Django的 - 多个用户配置文件

from django.db import models 
from django.contrib.auth.models import User 

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 
    verified = models.BooleanField() 
    mobile = models.CharField(max_length=32) 

    def __unicode__(self): 
     return self.user.email 

与在settings.pyAUTH_PROFILE_MODULE = 'accounts.UserProfile'组一直很好的作品。

但是,我的网站有两种不同类型的用户,分别是个人和公司,每个用户都有自己独特的属性。例如,我希望我的个人用户只有一个用户,因此有user = models.OneToOneField(User),对于公司我希望他们有多个用户相关的相同配置文件,所以我会有user = models.ForeignKey(User)而不是。

所以我想将模型分成两个不同的模型,IndivProfileCorpProfile,它们都从UserProfile继承,同时将模型特有的属性移动到相关的子模型中。似乎对我来说是一个好主意,可能会工作,但我不能指定AUTH_PROFILE_MODULE这种方式,因为我有两个用户配置文件,对于不同的用户会有所不同。

我也想过做周围用另一种方式,有多个类(模型),东西UserProfile继承这样的:

class UserProfile(IndivProfile, CorpProfile): 
    # some field 

    def __unicode__(self): 
     return self.user.email 

这样我会成立AUTH_PROFILE_MODULE = 'accounts.UserProfile'并解决它的问题。但是这看起来并不会奏效,因为python中的继承从左到右工作,并且IndivProfile中的所有变量都将占主导地位。

当然,我总是可以将一个模型与IndivProfileCorpProfile变量混合在一起,然后在必要时使用所需的变量。但是这对我来说看起来并不干净,我宁愿让他们隔离并在适当的地方使用合适的模型。

任何建议干净这样做的方式?

+0

[继承](https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance)呢? – danihp 2012-03-10 21:27:13

+1

我可以使'UserProfile'抽象,让'IndivProfile'和'CorpProfile'继承'UserProfile'。这仍然不能解决'AUTH_PROFILE_MODULE'问题。它将指向哪一个? – abstractpaper 2012-03-10 22:19:42

+0

如何将公司+个人+帐户类型字段添加到一个模型?如果你只有两种类型,我认为它可以是可以的,但如果你有两个以上的类型,或者那些配置文件是非常不同的,可能会很糟糕。 – 2012-03-10 22:24:30

回答

6

我已经这样做了。

PROFILE_TYPES = (
    (u'INDV', 'Individual'), 
    (u'CORP', 'Corporate'), 
) 

# used just to define the relation between User and Profile 
class UserProfile(models.Model): 
    user = models.ForeignKey(User) 
    profile = models.ForeignKey('Profile') 
    type = models.CharField(choices=PROFILE_TYPES, max_length=16) 

# common fields reside here 
class Profile(models.Model): 
    verified = models.BooleanField(default=False) 

最后我用一个中间表,以反映两个抽象模型,User这是在Django已经定义了,我Profile模型之间的关系。如果具有不常见的属性,我将创建一个新模型并将其与Profile关联。

+0

你是如何存储不常见的字段?你能为此显示代码吗? – user3411864 2016-11-07 05:26:32

-1

可能值得尝试使用直通领域。其背后的想法是使用UserProfile模型作为CorpProfile或IndivProfile模型的整个模型。创建用CorpProfile或IndivProfile

from django.db import models 
from django.contrib.auth.models import User 

class UserProfile(models.Model): 
    user = models.ForeignKey(User) 
    profile = models.ForeignKey(Profile, related_name='special_profile') 

class Profile(models.Model): 
    common_property=something 

class CorpProfile(Profile): 
    user=models.ForeignKey(User, through=UserProfile) 
    corp_property1=someproperty1 
    corp_property2=someproperty2 

class IndivProfile(Profile): 
    user=models.ForeignKey(User, through=UserProfile, unique=true) 
    indiv_property1=something 
    indiv_property2=something 

我认为事情应该是这样可以设置AUTH_PROFILE_MODULE = 'accounts.UserProfile',每次都:这样被只要一个公司或逐张个人资料链接到用户创建它即与真实用户相关联,创建唯一的UserProfile模型。然后你可以用db查询或任何你想要的来访问它。

我还没有测试过,所以没有保证。这可能有点冒失,但另一方面,我觉得这个想法非常有吸引力。 :)

+0

我试着运行这个,但它显示'无效的关键字参数'通过''错误。我目前在工作,无法得到确切的措辞。 – abstractpaper 2012-03-12 10:42:40

+0

糟糕,只能用于ManyToMany关系。看起来像另一个不那么干净的解决方案。但我认为Aamir已经提出了一个非常简单的解决方案。 – marue 2012-03-12 13:48:25

+0

@marue,这个答案应该完全删除吗?这是不正确的,似乎令人困惑。 – 2015-09-26 11:42:28

20

您可以通过以下方式完成此操作。有一个配置文件,其中将包含两个配置文件中必需的常用字段。而且你已经通过创建类UserProfile来完成此操作。

class UserProfile(models.Model): 
    user = models.ForeignKey(User) 
    #some common fields here, which are shared among both corporate and individual profiles 

class CorporateUser(models.Model): 
    profile = models.ForeignKey(UserProfile) 
    #corporate fields here 

    class Meta: 
     db_table = 'corporate_user' 

class IndividualUser(models.Model): 
    profile = models.ForeignKey(UserProfile) 
    #Individual user fields here 

    class Meta: 
     db_table = 'individual_user' 

这里没有涉及火箭科学。只需要有一个关键字可以区分公司简介或个人简介。例如。考虑用户正在注册。然后在表单上填写一个字段,以区别用户是否注册公司。并使用该关键字(请求参数)将用户保存在各自的模型中。

然后,当您想检查用户的个人资料是公司还是个人时,您可以通过编写一个小函数来检查它。

def is_corporate_profile(profile): 
    try: 
     profile.corporate_user 
     return True 
    except: 
     return False 

#If there is no corporate profile is associated with main profile then it will raise exception and it means its individual profile 
#you can use this function as a template function also to use in template 
{%if profile|is_corporate_profile %} 

希望这会带你到一些地方。 谢谢

+0

而不是一个[OneToOne](https://docs.djangoproject.com/en/dev/topics/db/models/#one-to-one-relationships)而不是一个ForeignKey? – danihp 2012-03-11 19:43:04

+0

指定外键也与oneToOne关系有关。 – 2012-03-11 19:49:38

+0

如果没有OneToOne,你应该写:'try:profile.corporate_user_set.all()[0]' – danihp 2012-03-11 20:04:13

相关问题