2010-07-11 9 views
29

मुझे Django उपयोगकर्ता मॉडल को विस्तारित करके UserProfile मॉडल बनाते समय OneToOneField (उपयोगकर्ता) या ForeignKey (उपयोगकर्ता, अद्वितीय = True) का उपयोग करने के बारे में विवादित जानकारी मिल रही है।Django: उपयोगकर्ता को विस्तारित करते समय, OneToOneField (उपयोगकर्ता) या ForeignKey (उपयोगकर्ता, अद्वितीय = सही) का उपयोग करने के लिए बेहतर?

बेहतर इस ?:

class UserProfile(models.Model): 
    user = models.ForeignKey(User, unique=True) 

उपयोग करने के लिए है या यह

class UserProfile(models.Model): 
    user = models.OneToOneField(User) 

Django Doc निर्दिष्ट करता OneToOneField ?:, जबकि Django Book example ForeignKey उपयोग करता है।

पूर्व पोस्ट में, बेनेट कुछ कारण वह बजाय ForeignKey उपयोग करने के लिए बंद कर देता है:

James Bennett भी दो ब्लॉग पोस्ट है कि परस्पर विरोधी उदाहरण प्रदान करने के साथ है OneToOneField का, लेकिन मुझे काफी कुछ नहीं मिलता है, खासकर जब मैं अन्य पोस्ट देखता हूं जो विपरीत की सिफारिश करते हैं।

मैं आपकी वरीयता जानने के लिए उत्सुक हूं और क्यों। या, क्या इससे कोई फर्क पड़ता है?

+0

मुझे उपयोगकर्ता प्रोफाइल के बारे में बेनेट के पहले लेख में कुछ भी नहीं दिखाई देता है। –

+0

@Ignacio - क्षमा करें, मैंने गलत आलेख का एक लिंक जोड़ा है। यह "यूजर मॉडल का विस्तार" पर अपनी पोस्ट के लिए होना चाहिए था। मैंने लिंक को सही किया है। इस पर ध्यान दिलाने के लिए धन्यवाद। –

+0

मेरे लिए, http://stackoverflow.com/questions/5870537/whats-the-difference-between-django-onetoonefield-and-foreignkey समझने के लिए और अधिक स्पष्ट है –

उत्तर

17

केवल असली कारण लेख में दी गई यह स्थापित किया जा सकता है कि इतना है कि User के लिए व्यवस्थापक पृष्ठ User और UserProfile में दोनों क्षेत्रों दिखाएगा है। इसे OneToOneField के साथ थोड़ा कोहनी ग्रीस के साथ दोहराया जा सकता है, इसलिए जब तक कि आप इसे स्पष्ट रूप से स्पष्ट रूप से लागत के बिना व्यवस्थापक पृष्ठ में दिखाने के आदी न हों ("हम प्रति उपयोगकर्ता एकाधिक प्रोफाइल बना सकते हैं ?! अरे नहीं , प्रतीक्षा करें, यह अद्वितीय सेट है। ") मैं OneToOneField का उपयोग करूंगा।

7

व्यवस्थापक पृष्ठ के अलावा, ForeignKey समाधान के अन्य कारण यह है कि यह आपको सही, डिफ़ॉल्ट डीबी प्रबंधक का उपयोग करने की अनुमति देता है जब वस्तुओं को रिवर्स रिलेशनशिप के साथ एक्सेस किया जाता है। इस subclasses manager snippet से उदाहरण पर विचार करें। मान लीजिए कि उदाहरण से Post वर्ग परिभाषा इस तरह दिखता है कि दो:

class Post(ParentModel): 
    title = models.CharField(max_length=50) 
    onetoone = models.ForeignKey(SomeModel, unique=True) 

    children = ChildManager() 
    objects = models.Manager() 

somemodel_instance.post_set.all()[0] बुला रखकर आप Post वर्ग के वांछित उपवर्गों वस्तुओं के रूप में एक ChildManager के रूप में पहली (डिफ़ॉल्ट) प्रबंधक को परिभाषित करते हुए संकेत दिया मिलता है। दूसरी ओर, OneToOneField के साथ, somemodel_instance.post पर कॉल करके आपको Post क्लास इंस्टेंस मिलता है। आप हमेशा somemodel_instance.post.subclass_object पर कॉल कर सकते हैं और एक ही परिणाम प्राप्त कर सकते हैं, लेकिन डिफ़ॉल्ट प्रबंधक किसी अन्य प्रकार की चाल कर सकता है और FK समाधान उन्हें अच्छी तरह से छुपाता है।

यदि आप कस्टम मैनेजर कोड के स्वामी हैं और संशोधित कर सकते हैं तो आप वैध 1to1 फ़ील्ड के स्थान पर एफके का उपयोग करने के बजाय use_for_related_fields विशेषता का उपयोग कर सकते हैं, लेकिन यहां तक ​​कि कुछ स्वचालित प्रबंधक के उपद्रव के कारण मुझे असफल भी हो सकता है। जहां तक ​​मुझे याद है कि यह उपर्युक्त उदाहरण में विफल हो जाएगा।

5

अन्य कारण आम तौर पर संबंधों को उल्टा करने के लिए संबंधित OneToOneField का उपयोग नहीं करने के लिए: जब आप ForeignKey रिवर्स संबंध के लिए और वहाँ हमेशा एक परिणाम के एक DB हिट के रूप में Manager को रिवर्स संबंधों OneToOneField के माध्यम से परिभाषित आप एक मॉडल उदाहरण मिल का उपयोग करें, इसके विपरीत।यह महंगा है यदि आप रिवर्स रिलेशनशिप पर कुछ सामान्य सामान करते हैं (_meta.get_all_related_objects() के माध्यम से) और यदि आप उनका उपयोग करेंगे या नहीं, तो उन्हें पता नहीं है और परवाह नहीं है।