2015-05-31 8 views
7

प्रसंगGenericForeignKey बनाम बहुमुखी विरासत बनाम OneToOneField का उपयोग करने के पेशेवरों और विपक्ष क्या हैं?

मैं Django मॉडल का उपयोग कर अपने डेटा मॉडलिंग की प्रक्रिया में हूँ। मुख्य मॉडल एक Article है। यह वास्तविक सामग्री रखती है।

फिर प्रत्येक Article लेखों के समूह से जुड़ा होना चाहिए। वे समूह Blog, CategoryPortfolio या Story हो सकते हैं। प्रत्येक Article एक से जुड़ा होना चाहिए, और उनमें से एक बिल्कुल। वह है, या तो एक ब्लॉग, एक श्रेणी या एक कहानी। उन मॉडलों में बहुत अलग फ़ील्ड और फीचर्स हैं।

मैंने उस लक्ष्य तक पहुंचने के तीन तरीकों के बारे में सोचा (और एक बोनस जो वास्तव में गलत दिखता है)।

विकल्प # 1: एक सामान्य विदेशी कुंजी

django.contrib.contenttypes.fields.GenericForeignKey में के रूप में। यह इस तरह दिखेगा:

class Category(Model): 
    # some fields 

class Blog(Model): 
    # some fields 

class Article(Model): 
    group_type = ForeignKey(ContentType) 
    group_id = PositiveIntegerField() 
    group = GenericForeignKey('group_type', 'group_id') 
    # some fields 

डेटाबेस पक्ष पर, इसका मतलब है कि कोई रिश्ता नहीं वास्तव में मॉडलों के बीच मौजूद है, वे Django द्वारा लागू कर रहे हैं।

विकल्प # 2: Multitable विरासत

मेक लेख समूह सब एक ArticleGroup मॉडल से विरासत। यह इस प्रकार दिखाई देगा:

class ArticleGroup(Model): 
    group_type = ForeignKey(ContentType) 

class Category(ArticleGroup): 
    # some fields 

class Blog(ArticleGroup): 
    # some fields 

class Article(Model): 
    group = ForeignKey(ArticleGroup) 
    # some fields 

डेटाबेस तरफ, इस ArticleGroup के लिए एक अतिरिक्त तालिका बनाता है, फिर Category और Blog उनके प्राथमिक कुंजी के रूप कि मेज पर एक अंतर्निहित विदेशी कुंजी है।

सिडेनोटे: मुझे पता है कि a package है जो इस तरह के निर्माण की बहीखाता को स्वचालित करता है।

विकल्प # 3: मैनुअल OneToOneFields

डेटाबेस पक्ष पर, यह # 2 विकल्प के बराबर है। लेकिन कोड में, सभी संबंधों को स्पष्ट किया जाता है:

class ArticleGroup(Model): 
    group_type = ForeignKey(ContentType) 

class Category(Model): 
    id = OneToOneField(ArticleGroup, primary_key=True) 
    # some fields 

class Blog(Model): 
    id = OneToOneField(ArticleGroup, primary_key=True) 
    # some fields 

class Article(Model): 
    group = ForeignKey(ArticleGroup) 
    # some fields 

मैं वास्तव में, नहीं दिख रहा है के अलावा स्पष्ट क्या Django के विरासत जादू परोक्ष करता करने से क्या इस बात का बिंदु होगा।

बोनस: एकाधिक

यह बहुत इतना गंदा मैं सिर्फ एक बोनस के रूप में जोड़ने लगता है, लेकिन यह भी Category, Blog से प्रत्येक के लिए एक नल ForeignKey को परिभाषित करना संभव हो सकता है, पर ... सीधे Article मॉडल।

तो ...

... मैं वास्तव में उन लोगों के बीच तय नहीं कर सकता। प्रत्येक दृष्टिकोण के पेशेवरों और विपक्ष क्या हैं? क्या कुछ सर्वोत्तम प्रथाएं हैं? क्या मुझे बेहतर दृष्टिकोण याद आया?

यदि यह मायने रखता है, तो मैं Django 1.8 का उपयोग कर रहा हूं।

उत्तर

4

ऐसा लगता है कि किसी को भी उस पर साझा करने की सलाह नहीं थी। मैंने अंततः बहुविकल्पीय विकल्प चुना, यह कहने के बावजूद कि यह बदसूरत लग रहा था। यह सब 3 चीजें नीचे आ गया:

  • डाटाबेस-आधारित प्रवर्तन योग्यता।
  • जिस तरह से Django ORM विभिन्न संरचनाओं के साथ काम करता है।
  • मेरी अपनी जरूरतें (अर्थात्, समूह सूची प्राप्त करने के लिए समूह पर संग्रह प्रश्न, और समूह प्राप्त करने के लिए वस्तुओं पर व्यक्तिगत प्रश्न)।

विकल्प # 1

  • डेटाबेस स्तर पर लागू नहीं किया जा सकता है।
  • प्रश्नों पर कुशल हो सकता है क्योंकि जिस तरह से इसका निर्माण किया गया है वह सामान्य सामान्य विदेशी कुंजी नुकसान में नहीं आता है। वे तब होते हैं जब आइटम जेनेरिक होते हैं, संग्रह नहीं।
  • हालांकि, ओआरएम कैसे जीएफके को संभालने के कारण, एक कस्टम मैनेजर का उपयोग करना असंभव है, जिसकी मुझे आवश्यकता है क्योंकि मेरे लेख का अनुवाद django-hvad का उपयोग करके किया जाता है।

विकल्प # 2

  • डेटाबेस स्तर पर लागू किया जा सकता है।
  • कुछ हद तक कुशल हो सकता है, लेकिन ओआरएम सीमाओं में चलता है, जो स्पष्ट रूप से इस उपयोग के आसपास नहीं बनाया गया है। जब तक मैं extra() या कस्टम प्रश्नों का बहुत उपयोग नहीं करता, लेकिन किसी बिंदु पर अब ORM का उपयोग करने का कोई कारण नहीं है।

विकल्प # 3

  • वास्तव में एक सा # 2 से बेहतर होगा, के रूप में चीजों को स्पष्ट आसान क्वेरी अनुकूलन की अनुमति देता है ORM का उपयोग करते समय बना रही है।

multicolumn

  • बाहर कर देता है इतना बुरा नहीं किया जा रहा। इसे डेटाबेस स्तर पर लागू किया जा सकता है (एफके बाधाओं के साथ मैनुअल चेक यह सुनिश्चित करने के लिए कि कॉलम में से केवल एक शून्य न हो)।
  • आसान और कुशल। एक सहज ज्ञान युक्त क्वेरी नौकरी करता है: select_related('category', 'blog', ...)
  • हालांकि इसमें विस्तार करने के लिए कठिन होने का मुद्दा है (किसी भी नए प्रकार को Article की तालिका को भी बदलने की आवश्यकता होगी) और संभावित प्रकारों को सीमित करने के लिए, मुझे उन लोगों में भाग लेने की संभावना नहीं है।

उम्मीद है कि यह किसी भी दुविधा के साथ किसी को भी मदद करता है, और फिर भी अन्य राय सुनने में रूचि रखता है।

+1

मैं सहमत हूं - बहु-स्तंभ विकल्प तब तक सबसे अच्छा है जब तक आप अनुमान लगाते हैं कि केवल सीमित संख्या में कक्षाएं हैं जिनसे संबंधित हो सकता है।इस उपयोग के मामले में, जीएफके बुराई आईएमओ है, क्योंकि यह आपके डेटाबेस अखंडता में एक छेद फेंकता है, और डीजेगो के बाहर विशेष रूप से कड़ी मेहनत करता है। – spookylukey

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

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