2012-11-12 14 views
5

मैं Django में निम्नलिखित मॉडल विरासत संरचना:Django फ़िल्टर बाल क्लास नाम से बेस कक्षा

class Parent(models.Model): 
    # stuff 

class A(Parent): 
    # stuff 

class B(Parent): 
    # stuff 

class C(Parent): 
    # stuff 

and the list goes on. 

मैं की तरह वस्तुओं फिल्टर करने के लिए Django मॉडल-utils का InheritanceManager उपयोग कर रहा हूँ:

Parent.objects.filter(foo=bar).select_subclasses() 

जब मैं सभी सबक्लास को फ़िल्टर करना चाहता हूं तो यह अच्छी तरह से काम करता है। मैं क्या करना चाहता हूं ए और बी ऑब्जेक्ट्स फ़िल्टर करना है, लेकिन सी ऑब्जेक्ट्स नहीं। मैं किसी एक क्वेरी के साथ ऐसा करना चाहते हैं की तरह

Parent.objects.filter(foo=bar, __class__.__name__=A, __class__.__name__=B).select_subclasses() 

यह इस तरह के एक छानने आपरेशन करने के लिए संभव है, और यदि संभव हो तो कैसे?

+0

क्यों न केवल 'एबजेक्ट्सफिल्टर (foo = bar) 'आदि? –

+0

मैं कई प्रश्नों के बजाय सभी क्वेरी को एक क्वेरी के साथ फ़िल्टर करना चाहता हूं, –

उत्तर

0

इसे आमतौर पर विरासत में स्थापित करने के लिए सबसे अच्छा नहीं माना जाता है क्योंकि तब प्रत्येक SQL क्वेरी में शामिल होना होगा। इससे आपका प्रदर्शन बहुत धीमा हो सकता है।

class Parent(models.Model): 
    # stuff 
    class Meta: 
     abstract = True 

इस तरह हर तालिका स्वतंत्र और इसलिए प्रदर्शन में तेजी से हो जाएगा: प्रदर्शन को बढ़ाने के लिए, आपको abstract मेटा मान का उपयोग कर सकते हैं।

यदि यह आपके लिए लागू नहीं है, तो मुझे लगता है कि ऐसा कुछ भी ऐसा करने में संभव नहीं है क्योंकि तालिका/मॉडल के भीतर के फ़ील्ड में कोई तालिका नहीं है कि वे किस तालिका में स्थित हैं। उस स्थिति में आपको किसी भी तरह InheritanceManager को उप-वर्ग करना होगा, हालांकि मुझे यकीन नहीं है कि वहां क्या करना है। यदि आप करते हैं, तो content_types का उपयोग करके कुछ मदद की जा सकती है।

यदि यह बहुत अधिक काम है, तो आप हमेशा एक साधारण हैक (एक बंदर पैचिंग के अधिक ...) कर सकते हैं। मैं अपनी सुंदर नहीं पता, लेकिन यह काम करेगा:

class Parent(models.Model): 
    # stuff 
    table = models.CharField(max_length=8, default='parent') 

class A(Parent): 
    # stuff 
    table = models.CharField(max_length=8, default='a') 

class B(Parent): 
    # stuff 
    table = models.CharField(max_length=8, default='b') 


# and then something like 
# please note that I've never used django-model-utils 
# so don't know the correct syntax 
Parent.objects.filter(foo=bar, table__in=['parent', 'a']).select_subclasses() 
+0

ठीक है धन्यवाद। मैंने एक सार आधार वर्ग का उपयोग नहीं किया क्योंकि मैं प्रत्येक उप-वर्ग के लिए एक अलग क्वेरी का उपयोग करने के बजाय एक एकल क्वेरी का उपयोग करके बेस क्लास ऑब्जेक्ट्स को फ़िल्टर करने की क्षमता चाहता था। मैं बस कुछ स्थानों पर बेस क्लास का एक सबसेट फ़िल्टर करना चाहता था, और दूसरा एक और स्थान सबसेट करता था। अगर मुझे संतोषजनक समाधान मिल जाए तो मैं यहां पोस्ट करूंगा –

0

एक और hacky समाधान है कि मेरे लिए काम किया है, डेटाबेस के लिए अधिक जानकारी के जोड़े बिना:

letters = Parent.objects.filter(foo=bar) 
for letter in letters: 
    if type(letter) == C: 
     letters.exclude(id=c.id) 

या, वैकल्पिक रूप से, आप में जानकारी जोड़ने अगर जोड़ने के खेतों के बिना मॉडल:

class Parent(models.Model): 
    # stuff 

class A(Parent): 
    code = 'A' 
    # stuff 

class B(Parent): 
    code = 'B' 
    # stuff 

class C(Parent): 
    code = 'C' 
    # stuff 

और फिर ...

letters = Parent.objects.filter(foo=bar) 
for letter in letters: 
    if letter.child().code == 'C': 
     letters.exclude(id=c.id) 

मेरे उद्देश्यों के लिए काम करता है, हालांकि अभी भी हैक ...

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