最初,我开始使用这样的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)
代替。
所以我考虑将模型分为两个不同的模型IndivProfile
和CorpProfile
,两者都继承自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
中的所有变量都占主导地位。
当然,我总是可以将一个模型与IndivProfile
和CorpProfile
变量混合在一起,然后我会在必要时使用所需的模型。但这对我来说看起来并不干净,我宁愿将它们隔离开来,并在适当的地方使用合适的模型。
干净这样做的任何建议?
答案 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,但在另一方面,我觉得这个想法非常吸引人。 :)