Django - 多个用户配置文件

Azi*_*ari 25 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
Run Code Online (Sandbox Code Playgroud)

哪个适用于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
Run Code Online (Sandbox Code Playgroud)

这样我就可以设置AUTH_PROFILE_MODULE = 'accounts.UserProfile'并解决它的问题.但是看起来它看起来不会起作用,因为python中的继承从左到右工作,所有变量IndivProfile都占主导地位.

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

的任何建议清洁这样的方式?

Aam*_*nan 24

您可以通过以下方式执行此操作.拥有一个配置文件,其中包含两个配置文件中必需的公共字段.你已经通过创建课程来完成这项工作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'
Run Code Online (Sandbox Code Playgroud)

这里没有涉及火箭科学.只需要一个能够区分公司资料或个人资料的关键字.例如,考虑用户正在注册.然后在表单上有一个字段,用于区分用户是否注册公司.并使用该关键字(请求参数)将用户保存在相应的模型中.

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

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 %}
Run Code Online (Sandbox Code Playgroud)

希望这能引领你到处.谢谢

  • 为了清楚起见:OneToOneField只是ForeignKey的Django内部包装器(unique = True).所以OTO不只是有点相关,它与ForeignKey完全相同. (6认同)
  • 最好不要使用[OneToOne](https://docs.djangoproject.com/en/dev/topics/db/models/#one-to-one-relationships)而不是ForeignKey吗? (2认同)

Azi*_*ari 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)
Run Code Online (Sandbox Code Playgroud)

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