2012-03-10 102 views
19

最初,我開始了我的用戶配置是這樣的:Django的 - 多個用戶配置文件

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 

與在settings.pyAUTH_PROFILE_MODULE = 'accounts.UserProfile'組一直很好的作品。

但是,我的網站有兩種不同類型的用戶,分別是個人和公司,每個用戶都有自己獨特的屬性。例如,我希望我的個人用戶只有一個用戶,因此有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變量混合在一起,然後在必要時使用所需的變量。但是這對我來說看起來並不乾淨,我寧願讓他們隔離並在適當的地方使用合適的模型。

任何建議乾淨這樣做的方式?

+0

[繼承](https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance)呢? – danihp 2012-03-10 21:27:13

+1

我可以使'UserProfile'抽象,讓'IndivProfile'和'CorpProfile'繼承'UserProfile'。這仍然不能解決'AUTH_PROFILE_MODULE'問題。它將指向哪一個? – abstractpaper 2012-03-10 22:19:42

+0

如何將公司+個人+帳戶類型字段添加到一個模型?如果你只有兩種類型,我認爲它可以是可以的,但如果你有兩個以上的類型,或者那些配置文件是非常不同的,可能會很糟糕。 – 2012-03-10 22:24:30

回答

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關聯。

+0

你是如何存儲不常見的字段?你能爲此顯示代碼嗎? – user3411864 2016-11-07 05:26:32

-1

可能值得嘗試使用直通領域。其背後的想法是使用UserProfile模型作爲CorpProfile或IndivProfile模型的整個模型。創建用CorpProfile或IndivProfile

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',每次都:這樣被只要一個公司或逐張個人資料鏈接到用戶創建它即與真實用戶相關聯,創建唯一的UserProfile模型。然後你可以用db查詢或任何你想要的來訪問它。

我還沒有測試過,所以沒有保證。這可能有點冒失,但另一方面,我覺得這個想法非常有吸引力。 :)

+0

我試着運行這個,但它顯示'無效的關鍵字參數'通過''錯誤。我目前在工作,無法得到確切的措辭。 – abstractpaper 2012-03-12 10:42:40

+0

糟糕,只能用於ManyToMany關係。看起來像另一個不那麼幹淨的解決方案。但我認爲Aamir已經提出了一個非常簡單的解決方案。 – marue 2012-03-12 13:48:25

+0

@marue,這個答案應該完全刪除嗎?這是不正確的,似乎令人困惑。 – 2015-09-26 11:42:28

20

您可以通過以下方式完成此操作。有一個配置文件,其中將包含兩個配置文件中必需的常用字段。而且你已經通過創建類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 %} 

希望這會帶你到一些地方。 謝謝

+0

而不是一個[OneToOne](https://docs.djangoproject.com/en/dev/topics/db/models/#one-to-one-relationships)而不是一個ForeignKey? – danihp 2012-03-11 19:43:04

+0

指定外鍵也與oneToOne關係有關。 – 2012-03-11 19:49:38

+0

如果沒有OneToOne,你應該寫:'try:profile.corporate_user_set.all()[0]' – danihp 2012-03-11 20:04:13

相關問題