2009-10-17 10 views
5

मैं एक मॉडलDjango विरासत: सभी उपclasses के लिए एक विधि कैसे है?

BaseModel 

और कई यह

ChildModelA(BaseModel), ChildModelB(BaseModel), ... 

की उपवर्गों मल्टी-टेबल वंशानुक्रम का उपयोग कर सकते है। भविष्य में मैं दर्जनों सबक्लास मॉडल बनाने की योजना बना रहा हूं।

सभी उपवर्गों विधि

do_something() 

मैं एक BaseModel उदाहरण से do_somthing कैसे फोन कर सकते हैं में से कुछ कार्यान्वयन है?

लगभग समान समस्या (समाधान के बिना) यहां पोस्ट है:
http://peterbraden.co.uk/article/django-inheritance

एक सरल प्रश्न: कैसे मैं सभी संभव उपवर्गों की जाँच के बिना अपनी उपवर्गों उदाहरण से एक के लिए BaseModel instnace हल?

उत्तर

1

क्या आप कभी भी मूल प्रकार के उदाहरण के साथ काम करेंगे या आप हमेशा बच्चों के उदाहरणों के साथ काम करेंगे? यदि उत्तरार्द्ध मामला है तो विधि को कॉल करें, भले ही आपके पास बेस प्रकार का संदर्भ हो, क्योंकि ऑब्जेक्ट स्वयं आई-ए बच्चे का प्रकार है।

चूंकि पायथन समर्थन duck typing का मतलब है कि आपका विधि कॉल उचित रूप से बॉन्ड होगा क्योंकि बच्चे के उदाहरण में वास्तव में यह विधि होगी।

एक pythonic प्रोग्रामिंग शैली जो इसकी विधि या विशेषता हस्ताक्षर की निरीक्षण के बजाय कुछ प्रकार वस्तु को स्पष्ट रिश्ते से एक वस्तु के प्रकार ("यह एक बतख की तरह लग रहा है और एक तरह नीम हकीमों हैं बतख, यह एक बतख होना चाहिए। ") विशिष्ट प्रकारों के बजाय इंटरफेस पर जोर देते हुए, अच्छी तरह से डिज़ाइन किया गया कोड पॉलिमॉर्फिक प्रतिस्थापन की अनुमति देकर इसकी लचीलापन में सुधार करता है। बतख-टाइपिंग टाइप() या isinstance() का उपयोग करके परीक्षण से बचाता है। (नोट, हालांकि, बतख-टाइपिंग को सार आधार वर्गों के साथ पूरक किया जा सकता है।) इसके बजाय, यह आमतौर पर हैटट्र() परीक्षण या ईएएफपी प्रोग्रामिंग को नियोजित करता है।

ध्यान दें कि EAFP Easier to Ask Forgiveness than Permission के लिए खड़ा है:

आसान अनुमति से माफी के लिए पूछने की। यह सामान्य पायथन कोडिंग शैली वैध कुंजी या विशेषताओं के अस्तित्व को मानती है और धारणा झूठी साबित होती है तो अपवादों को पकड़ लेती है। यह साफ और तेज़ शैली कई कोशिशों और बयानों को छोड़कर उपस्थिति की विशेषता है। तकनीक एलबीवाईएल शैली के साथ कई अन्य भाषाओं जैसे सी

+1

यह सब सही है, लेकिन इस मामले में प्रासंगिक नहीं है। मुद्दा यह है कि Django बहु-टेबल विरासत के साथ काम करते समय, अक्सर एक बेस क्लास का उदाहरण होता है (यानी आधार तालिका से पूछताछ से), भले ही ऑब्जेक्ट एक बच्चे के प्रकार का "वास्तव में" है (यानी इसके अनुरूप है एक बच्चे की मेज में प्रवेश)। –

0

मैं एंड्रयू के साथ सहमत हूं। कुछ साइटों पर हमारे पास एक वर्ग है जो विधियों के पूरे समूह का समर्थन करता है (लेकिन फ़ील्ड नहीं (यह प्री-ओआरएम रिफैक्टर था)) जो हमारे सभी सामग्री वर्गों के लिए सबसे आम हैं। वे हैड्रेट का उपयोग उन जगहों पर बैठने के लिए करते हैं जहां विधि समझ में नहीं आती है।

इसका मतलब यह है हमारे वर्गों में से अधिकांश के रूप में परिभाषित कर रहे हैं: मूल रूप से यह एक तरह से बात की एक Mixin प्रकार है

class Foo(models.Model, OurKitchenSinkClass): 

। बनाए रखने के लिए आसान, आसान काम करता है।

2

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

def resolve(self): 
    module, cls_name = self.class_name.rsplit(".",1) 
    module = import_module(module) 
    cls = getattr(module, cls_name) 
    return cls.objects.get(pk=self.pk) 

इस उत्तर मुझे खुश नहीं कर सकता और मैं भी एक बेहतर समाधान को देखने के लिए प्यार होता है, जैसा कि मैंने एक ऐसी ही समस्या का सामना करना पड़ जल्द ही हो जाएगा: अपने आधार वर्ग इस तरह की एक विधि हो सकता है।

+0

यह अनिवार्य रूप से आपको करना है, लेकिन इसे करने के लिए क्लीनर तरीके हैं (contrib.contenttypes का उपयोग करके)। मेरा जवाब देखें –

+0

हैलो कार्ल, मैं आपका जवाब देखने में सक्षम नहीं हूं। क्या आप शायद दोबारा पोस्ट कर सकते हैं, या एक सहायक लिंक दे सकते हैं। धन्यवाद –

+0

कोई बात नहीं, मुझे मिल गया। आपकी व्याख्या के लिए कार्ल धन्यवाद। –

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