Django - 多个用户配置文件

时间:2012-03-10 20:58:53

标签: django django-models django-users

最初,我开始使用这样的UserProfile:

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

AUTH_PROFILE_MODULE = 'accounts.UserProfile'中设置的settings.py一起使用效果很好。

但是,我的网站中有两种不同的用户,个人和企业,每个都有自己独特的属性。例如,我希望我的个人用户只有一个用户,因此有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变量混合在一起,然后我会在必要时使用所需的模型。但这对我来说看起来并不干净,我宁愿将它们隔离开来,并在适当的地方使用合适的模型。

干净这样做的任何建议?

3 个答案:

答案 0 :(得分:22)

您可以通过以下方式执行此操作。拥有一个配置文件,其中包含两个配置文件中必需的公共字段。您已经通过创建课程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 %}

希望这能引领你到处。 感谢

答案 1 :(得分: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相关联。

答案 2 :(得分:-1)

值得尝试使用直通字段。其背后的想法是使用UserProfile模型作为CorpProfile或IndivProfile模型的模型。这样,只要Corp或Indiv Profile链接到用户,就会创建它:

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',每次创建链接到真实用户的CorpProfile或IndivProfile时,都会创建一个唯一的UserProfile模型。然后,您可以使用db查询或任何您想要的方式访问它。

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