Django-多个用户个人资料

问题描述 投票:26回答:3

起初,我是这样启动我的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变量都混合在一起,然后在必要时使用所需的模型。但这对我来说似乎并不干净,我宁愿将它们隔离开来,并在适当的地方使用适当的模型。

关于干净方法的任何建议吗?

django django-models django-users
3个回答
25
投票

您可以按照以下方式进行操作。有一个配置文件,其中将包含两个配置文件中必需的公共字段。并且您已经通过创建类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 CorporateUser.DoesNotExist:
        return False

# If there is no corporate profile is associated with main profile then it will raise `DoesNotExist` 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 %}

希望这会引导您到某个地方。谢谢!


8
投票

我已经这样做了。

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)

我最终使用了一个中间表来反映两个抽象模型(已经在Django中定义的User和我的Profile模型)之间的关系。如果属性不常见,我将创建一个新模型并将其与Profile关联。


-1
投票

可能值得尝试使用直通字段。其背后的想法是将UserProfile模型用作CorpProfile或IndivProfile模型的直通模型。这样,只要将Corp或Indiv个人资料链接到用户即可创建它:

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模型。然后,您可以使用数据库查询或任何您想要的内容访问它。

我尚未对此进行测试,因此无法保证。这可能有点怪癖,但另一方面,我发现这个想法很吸引人。 :)

© www.soinside.com 2019 - 2024. All rights reserved.