2012-03-10 3 views
19

プロファイル、私はこのように私のUserProfileを開始しました。ジャンゴ複数のユーザが最初

私のウェブサイトには、自分のユニークな属性を持つ個人と企業の2種類のユーザーがいます。たとえば、個人ユーザーには単一のユーザーしかいないため、user = models.OneToOneField(User)が必要です。企業では、同じプロファイルに関連する複数のユーザーがいるようにしたいので、代わりにuser = models.ForeignKey(User)が必要です。

IndivProfileCorpProfileという2つの異なるモデルにモデルを分離することを考えました。モデル固有の属性を関連するサブモデルに移動しながら、両方ともUserProfileから継承しました。私には良いアイデアのように思えますが、おそらくうまくいくでしょうが、私はAUTH_PROFILE_MODULEをこの方法で指定することはできません。ユーザーごとに異なる2つのユーザープロファイルがあるからです。

私はまた、このような何か、それを他の方法で回避を行う複数のクラス(モデル)からUserProfile継承を持っていることについて考えた:私はAUTH_PROFILE_MODULE = 'accounts.UserProfile'を設定し、その問題を解決するだろう

class UserProfile(IndivProfile, CorpProfile): 
    # some field 

    def __unicode__(self): 
     return self.user.email 

この道を。しかし、Pythonの継承は左から右に動作し、IndivProfileのすべての変数が支配的になるので、それはうまくいくようには見えません。

確かに、私はいつもIndivProfileCorpProfileの変数が混在している単一のモデルを常に持っていて、必要なところで必要なものを使用します。しかし、それはちょうど私にきれいに見えません、私はむしろそれらを分離し、適切なモデルを適切な場所で使用するでしょう。

クレンズこれはどのような方法ですか?

+0

[継承](https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance)はどうですか? – danihp

+1

私は 'UserProfile'を抽象化し、' IndivProfile'と 'CorpProfile'を' UserProfile'から継承させることができました。これはまだ 'AUTH_PROFILE_MODULE'の問題を解決するつもりはありません。どちらを指すつもりですか? – abstractpaper

+0

corporate + individual + account_typeフィールドを1つのモデルに追加する方法はありますか?私はあなたが2つのタイプしか持っていないとOKかもしれませんが、2つ以上のプロファイルを持っていると悪いかもしれません。 –

答えて

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) 

私はすでにジャンゴに定義されている2つの抽象モデル、Userとの関係、そして私のProfileモデルを反映するように、中間テーブルを使用して終了。共通でない属性がある場合は、新しいモデルを作成してProfileに関連付けます。

+0

珍しいフィールドをどのように保存しましたか?そのコードを表示できますか? – user3411864

-1

スルーフィールドを試してみる価値があります。その背後にあるアイデアは、UserProfileモデルをCorpProfileまたはIndivProfileモデルのモデルを介して使用することです。それはできるだけ早く株式会社または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モデルが作成されます。その後、dbクエリなどでアクセスできます。

私はこれをテストしていないので、保証はありません。それは少しハッキーかもしれませんが、反対側で私は非常に魅力的なアイデアを見つける。 :)

+0

私はこれを実行しようとしましたが、 'invalid keyword argument 'through'エラーが表示されました。私は現時点で仕事中であり、正確な言葉を得ることはできません。 – abstractpaper

+0

おっと、スルースルーはManyToManyリレーションシップでのみ機能します。他の清潔なソリューションではないように見えます。しかし、私はAamirが既に非常に簡単な解決法を提案したと思う。 – marue

+0

@marue、この回答は完全に削除する必要がありますか?それは間違っており、混乱しているようです。 –

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/ja/dev/topics/db/models/#one-to-one-relationships)ではなく、ForeignKey? – danihp

+0

外部キーの指定は、oneToOne関係に関連するものもあります。 –

+0

OneToOneがない場合は、次のように記述する必要があります。 'try:profile.corporate_user_set.all()[0]' – danihp

関連する問題