2012-03-10 21 views
19

प्रारंभ में, मैं इस तरह मेरी UserProfile शुरू कर दिया।Django एकाधिक उपयोगकर्ता प्रोफाइल

हालांकि, मेरे पास अपनी वेबसाइट, व्यक्तियों और कॉर्पोरेट में दो अलग-अलग प्रकार के उपयोगकर्ता हैं, जिनमें से प्रत्येक के अपने अद्वितीय गुण हैं। उदाहरण के लिए, मैं चाहता हूं कि मेरे व्यक्तिगत उपयोगकर्ताओं के पास केवल एक उपयोगकर्ता हो, इसलिए 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' सेट और उसके समस्या का समाधान होगा। लेकिन ऐसा लगता है कि यह काम करने जा रहा है, क्योंकि पाइथन में विरासत बाएं से दाएं काम करती है और IndivProfile में सभी चर प्रभावी होंगे।

निश्चित रूप से मैं हमेशा IndivProfile और CorpProfile चर के साथ एक एकल मॉडल रख सकता हूं जो सभी एक साथ मिश्रित होते हैं और फिर आवश्यकतानुसार आवश्यकतानुसार उपयोग करेंगे। लेकिन यह सिर्फ मुझे साफ नहीं दिखता है, बल्कि मैं उन्हें अलग-अलग जगह पर उपयुक्त मॉडल का उपयोग और उपयोग कर दूंगा।

के कोई सुझाव यह करने का तरीका साफ है?

+0

[विरासत] (https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance) के बारे में क्या? – danihp

+1

मैं 'UserProfile' सार बना सकता हूं और' IndivProfile' और 'CorpProfile' को 'UserProfile' से प्राप्त कर सकता हूं। यह अभी भी 'AUTH_PROFILE_MODULE' के साथ इस मुद्दे को हल करने वाला नहीं है। यह किस पर इंगित करने जा रहा है? – abstractpaper

+0

कॉर्पोरेट + व्यक्तिगत + खाता_ प्रकार फ़ील्ड को एक मॉडल में जोड़ने के बारे में कैसे? मुझे लगता है कि यह ठीक हो सकता है यदि आपके पास केवल दो प्रकार हैं, लेकिन यदि आपके पास 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) 

मैं दो सार मॉडल, User जो पहले से ही Django में परिभाषित किया गया है, और मेरे Profile मॉडल के बीच संबंध को प्रतिबिंबित करने के लिए एक मध्यवर्ती तालिका का उपयोग कर समाप्त हो गया। ऐसे गुण होने के मामले में जो सामान्य नहीं हैं, मैं एक नया मॉडल तैयार करूंगा और इसे Profile से जोड़ूंगा।

+0

आपने असामान्य फ़ील्ड को कैसे स्टोर किया? क्या आप इसके लिए कोड दिखा सकते हैं? – user3411864

-1

फ़ील्ड का उपयोग करने का प्रयास करने के लायक हो सकता है। इसके पीछे विचार उपयोगकर्ताप्रोफाइल मॉडल को कॉर्पप्रोफाइल या इंडिवप्रोफाइल मॉडल के मॉडल के माध्यम से उपयोग करना है। यही कारण है कि जिस तरह से यह जैसे ही एक कॉर्प या व्यक्ति प्रोफाइल एक उपयोगकर्ता से जुड़ा हुआ है बनाया जा रहा है:

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 मॉडल बनाया गया है। इसके बाद आप उस डीबी प्रश्नों या जो कुछ भी चाहते हैं उसे एक्सेस कर सकते हैं।

मैंने इसका परीक्षण नहीं किया है, इसलिए कोई गारंटी नहीं है। यह थोड़ा सा हैकी हो सकता है, लेकिन दूसरी ओर मुझे यह विचार काफी आकर्षक लगता है। :)

+0

मैंने इसे चलाने का प्रयास किया है लेकिन यह 'त्रुटि के माध्यम से' अवैध कीवर्ड तर्क 'दिखाता है। मैं इस समय काम पर हूं और सटीक शब्द नहीं प्राप्त कर सकता हूं। – abstractpaper

+0

ओह, केवल कई सारे संबंधों के लिए काम करता है। ऐसा लगता है कि अब एक और साफ समाधान नहीं है। लेकिन मुझे लगता है कि आमिर ने पहले से ही काफी सरल समाधान का प्रस्ताव दिया है। – 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/en/dev/topics/db/models/#one-to-one-relationships) बेहतर नहीं है? – danihp

+0

विदेशी कुंजी निर्दिष्ट करना कुछ भी एक रिश्ते से संबंधित है। –

+0

बिना OneToOne आपको लिखना चाहिए: 'try: profile.corporate_user_set.all() [0] ' – danihp

संबंधित मुद्दे