起初,我是这样启动我的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
变量都混合在一起,然后在必要时使用所需的模型。但这对我来说似乎并不干净,我宁愿将它们隔离开来,并在适当的地方使用适当的模型。
关于干净方法的任何建议吗?
您可以按照以下方式进行操作。有一个配置文件,其中将包含两个配置文件中必需的公共字段。并且您已经通过创建类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 %}
希望这会引导您到某个地方。谢谢!
我已经这样做了。
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
关联。
可能值得尝试使用直通字段。其背后的想法是将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模型。然后,您可以使用数据库查询或任何您想要的内容访问它。
我尚未对此进行测试,因此无法保证。这可能有点怪癖,但另一方面,我发现这个想法很吸引人。 :)