model.py विशाल हो रहा है, इसे तोड़ने का सबसे अच्छा तरीका क्या है?


91

मेरे पर्यवेक्षक के निर्देश: "मैं किसी भी तर्क को अंदर डालने से बचना चाहता हूँ models.py। यहाँ से, डेटाबेस का उपयोग करने के लिए केवल कक्षाओं के रूप में उपयोग करते हैं, और बाहरी कक्षाओं में सभी तर्क रखते हैं जो मॉडल कक्षाओं का उपयोग करते हैं, या उन्हें लपेटते हैं।"

मुझे लगता है कि यह जाने का गलत तरीका है। मुझे लगता है कि केवल फ़ाइल को छोटा रखने के लिए मॉडल से तर्क रखना एक बुरा विचार है। यदि तर्क मॉडल में सबसे अच्छा है, तो यह वह जगह है जहां फ़ाइल आकार की परवाह किए बिना वास्तव में जाना चाहिए।

तो क्या सिर्फ उपयोग करने का एक सरल तरीका है? PHP-Speak में, मैं पर्यवेक्षक को प्रस्ताव देना चाहूंगा कि हमने models.pyअन्य स्थानों के मॉडल वर्गों को शामिल किया है। वैचारिक रूप से, यह मॉडल को उन सभी तर्कों की अनुमति देता है जो हम चाहते हैं, फिर भी फाइल की संख्या को बढ़ाने के माध्यम से फ़ाइल का आकार नीचे रखें (जिससे संघर्ष की तरह कम संशोधन नियंत्रण समस्याएं होती हैं)।

तो, क्या मॉडल कक्षाओं को मॉडल-थ्रेड फ़ाइल से हटाने का एक सरल तरीका है, लेकिन फिर भी सभी Django टूल के साथ मॉडल काम करते हैं? या, एक "बड़े" मॉडल की फ़ाइल की सामान्य समस्या के लिए पूरी तरह से अलग सुरुचिपूर्ण समाधान है? किसी भी इनपुट की सराहना की जाएगी।


7
आप आयात विवरण जानते हैं, है ना?
बाल्फा

7
पुनश्च। मेरा मतलब यह नहीं है कि आपत्तिजनक रूप से, मैं सिर्फ यह जानना चाहता हूं कि आप कहां हैं।
बाल्फा जूल

1
हां, लेकिन मुझे नहीं पता था कि django के एडमिन टूल मॉडल्स में खींचने के लिए सिर्फ इंपोर्टेंट स्टेटमेंट का उपयोग करके काम करेंगे। मैं यहाँ बहुत समय बिताने के बजाय सादे ओले के आयात का उपयोग करने की कोशिश कर रहा हूं, ताकि यह पता चल सके कि django के उपकरण उनके साथ अच्छा नहीं खेलते हैं। मैं मानता हूँ कि मैं अजगर और django के लिए नया हूं, इसलिए मैं शायद केवल आयात कथन की एक सरल समझ पर हूं ...
Eddified

जवाबों:


64

Django को एक बड़े एप्लिकेशन के बजाय कई छोटे एप्लिकेशन बनाने के लिए डिज़ाइन किया गया है।

हर बड़े अनुप्रयोग के अंदर कई छोटे अनुप्रयोग मुक्त होने के लिए संघर्ष कर रहे हैं।

यदि आपका models.pyबड़ा लगता है, तो आप बहुत अधिक कर रहे हैं। रूक जा। आराम करें। विघटित।

छोटे, संभावित पुन: प्रयोज्य छोटे अनुप्रयोग घटकों, या टुकड़ों का पता लगाएं। आपको वास्तव में उनका पुन: उपयोग नहीं करना है। बस संभावित पुन: प्रयोज्य के बारे में उनके बारे में सोचो।

अपने अपग्रेड पथों पर विचार करें और उन अनुप्रयोगों को विघटित करें जिन्हें आप किसी दिन बदलना चाहते हैं। आपको वास्तव में उन्हें बदलने की ज़रूरत नहीं है , लेकिन आप उन्हें प्रोग्रामिंग के स्टैंड-अलोन "मॉड्यूल" के रूप में मान सकते हैं जो भविष्य में कुछ कूलर के साथ मिल सकता है।

हमारे पास लगभग एक दर्जन एप्लिकेशन हैं, प्रत्येक model.pyकोड की लगभग 400 लाइनों से अधिक नहीं है। वे सभी बहुत कम से कम आधा दर्जन से अधिक असतत वर्ग परिभाषाओं पर ध्यान केंद्रित कर रहे हैं। (ये कठिन सीमाएँ नहीं हैं, ये हमारे कोड के बारे में हैं।)

हम जल्दी और अक्सर विघटित होते हैं।


1
सही बात पर। कोई भी गैर-तुच्छ वेबप कई छोटे 'ऐप्स' होंगे। कॉन्ट्रिब और अन्य लोकप्रिय ऐप्स का एक संकेत लें, उपयोगकर्ता प्रमाणीकरण एक ऐप है, टैगिंग एक और है, उपयोगकर्ता प्रोफाइल एक और, आदि
जेवियर

4
हालांकि यह "सही" तरीका है, और जानने में मददगार है, यह वह नहीं है जो मैं खोज रहा था। मैं माफी माँगता हूँ अगर वहाँ पता करने के लिए कोई रास्ता नहीं था कि मैं किस तरह के जवाब की तलाश में था। :)
संपादित किया

@ संशोधित: यदि आप ऐसा नहीं करते हैं, तो यह केवल खराब होने वाला है। अब बंटवारा शुरू करो।
एस.लॉट जूथ

काफी मज़ेदार, इस क्षण मैं जैकब कापलान मॉस (OSCON पर) को यह सुनकर समझा रहा हूँ कि यह महान और दृढ़ता से उचित विवरण है;;
एलेक्स मार्टेली जूल 21'09

13
इस पर ग्लेन मेनार्ड का जवाब बेहतर है। एक जटिल वेबएप को कई ऐप में विभाजित करना निश्चित रूप से एक अच्छा अभ्यास है, लेकिन इसलिए ऐप के साथ एक मॉडल-थ्रू फ़ाइल को फिर से बनाना है। दो क्रियाएं ऑर्थोगोनल हो सकती हैं।
एरिक

108

मॉडल पर मॉडल को संचालित करने के लिए मॉडल वर्गों के लिए यह स्वाभाविक है। अगर मेरे पास कोई बुक मॉडल है, तो एक विधि के साथ book.get_noun_count(), वह जहां है - मैं " get_noun_count(book)" लिखना नहीं चाहता , जब तक कि विधि वास्तव में आंतरिक रूप से किसी अन्य पैकेज के साथ न हो। (यह हो सकता है - उदाहरण के लिए, अगर मेरे पास " get_amazon_product_id(book)" के साथ अमेज़ॅन के एपीआई तक पहुंचने के लिए एक पैकेज है ।)

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

site/models/__init__.py
site/models/book.py

__init__.py की तरह लगता है:

from .book import Book

इसलिए मैं अभी भी "site.models इंपोर्ट बुक से" लिख सकता हूं।


निम्नलिखित केवल Django 1.7 से पहले के संस्करणों के लिए आवश्यक है, https://code.djangoproject.com/ticket/3591 देखें

एकमात्र चाल यह है कि आपको प्रत्येक मॉडल के एप्लिकेशन को स्पष्ट रूप से सेट करने की आवश्यकता है, जो Django में एक बग के कारण है: यह मानता है कि आवेदन का नाम मॉडल पथ में तीसरे से अंतिम प्रविष्टि है। "site.models.Book" परिणाम "साइट" में, जो सही है; "site.models.book.Book" यह सोचता है कि एप्लिकेशन का नाम "मॉडल" है। यह Django के हिस्से पर एक बहुत बुरा हैक है; यह शायद एक उपसर्ग मैच के लिए स्थापित अनुप्रयोगों की सूची खोजना चाहिए।

class Book(models.Model):
    class Meta: app_label = "site"

आप शायद इसे सामान्य बनाने के लिए एक बेस क्लास या मेटाक्लस का उपयोग कर सकते हैं, लेकिन मैंने अभी तक इससे परेशान नहीं किया है।


2
+1 मैंने सफलता के साथ इसका उपयोग किया है। जबकि एस। लोट्टो एक अच्छा विचार होने के नाते कई ऐप में सही है, यह यहाँ और अब समाधान है।
अलेक्जेंडर लजबर्गबर्ग

35
जब आपके मॉडल निकट और आंतरिक रूप से संबंधित होते हैं, तो मुझे ऐप के झुंड में चीजों को विभाजित करने का अधिक लाभ नहीं दिखता है।
ग्लेन मेनार्ड

2
यह मुझे रुचता है। मैंने पोस्ट की गई django wiki लिंक scompt को पढ़ा और पाया कि: "इसे मेटा क्लास app_labels के बिना वर्तमान मुख्य शाखा में काम करने के लिए सत्यापित किया गया है।" तो क्या इसका मतलब है कि यदि आप मुख्य शाखा के साथ काम कर रहे हैं तो हम मेटा: app_label सामान को छोड़ सकते हैं? इस समस्या को हल करने के लिए टिकट के बारे में टिप्पणी के बाद यह भ्रामक है।
Dan.StackOverflow

2
मैंने सिर्फ ट्रंक के साथ परीक्षण किया (जैसा कि पहले आज, r11286); यदि app_name सेट नहीं है, तो मॉडल केवल "sqlall appname" में दिखाई नहीं देता है और शायद syncdb द्वारा नहीं बनाया जाएगा (लेकिन मैं इसका उपयोग नहीं करता हूं इसलिए मैं इसका परीक्षण नहीं कर सकता)। यह काफी भ्रामक त्रुटि मामला है, क्योंकि यह किसी भी त्रुटि को ट्रिगर नहीं करता है; यह केवल चुपचाप नहीं दिखाता है।
ग्लेन मेनार्ड

2
वाह, लगभग 10 साल बाद और मैं अभी भी इस समाधान से प्यार करता हूं। सहमत थे कि अपने कोड को छोटे ऐप्स में विभाजित करने की तुलना में यह एक बेहतर तरीका है, जो मेरी राय में एक कोडबेस हो सकता है, जिसके बारे में तर्क करना मुश्किल है।
माइकल हेस

5

मैं आपको बहुत सी संभावित समस्याओं से छुटकारा नहीं दिला सकता। यहाँ उत्तर के साथ कुछ संभावनाएँ हैं:

  • एक ही फाइल में कई मॉडल

    उन्हें अलग-अलग फाइलों में डालें। यदि निर्भरताएं हैं, तो अतिरिक्त मॉडल में खींचने के लिए आयात का उपयोग करें।

  • मॉडल तर्क में extraneous तर्क / उपयोगिता कार्य

    अतिरिक्त तर्क को अलग-अलग फ़ाइलों में रखें।

  • डेटाबेस से कुछ मॉडल उदाहरणों के चयन के लिए स्थैतिक तरीके

    एक अलग फ़ाइल में एक नया प्रबंधक बनाएँ ।

  • तरीके स्पष्ट रूप से मॉडल से संबंधित हैं

    सहेजें, __unicode__ और get_absolute_url इसके उदाहरण हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.