2011-09-23 27 views
7

के साथ django मॉडल polymorphism मेरा Discount मॉडल सिस्टम में सभी प्रकार की छूट के लिए सामान्य क्षेत्रों का वर्णन करता है। मेरे पास कुछ प्रॉक्सी मॉडल हैं जो कुल मिलाकर कंक्रीट एल्गोरिदम का वर्णन करते हैं। बेस Discount कक्षा में type नामक एक सदस्य फ़ील्ड है, जो एक प्रकार है जो इसके प्रकार और इसकी संबंधित कक्षा को पहचानता है।प्रॉक्सी विरासत

class Discount(models.Model): 
    TYPE_CHOICES = (
    ('V', 'Value'), 
    ('P', 'Percentage'), 
) 

    name = models.CharField(max_length=32) 
    code = models.CharField(max_length=32) 
    quantity = models.PositiveIntegerField() 
    value = models.DecimalField(max_digits=4, decimal_places=2) 
    type = models.CharField(max_length=1, choices=TYPE_CHOICES) 

    def __unicode__(self): 
    return self.name 

    def __init__(self, *args, **kwargs): 
    if self.type: 
     self.__class__ = getattr(sys.modules[__name__], self.type + 'Discount') 
    super(Discount, self).__init__(*args, **kwargs) 

class ValueDiscount(Discount): 
    class Meta: 
    proxy = True 

    def total(self, total): 
    return total - self.value 

लेकिन मुझे विशेषता योगदान का अपवाद मिल रहा है जिसमें स्वयं का प्रकार नहीं है। इसे कैसे ठीक किया जाए या यह हासिल करने का कोई और तरीका है?

उत्तर

11

आपका init विधि इस बजाय की तरह लग रहे करने की जरूरत है:

def __init__(self, *args, **kwargs): 
    super(Discount, self).__init__(*args, **kwargs) 
    if self.type: 
     self.__class__ = getattr(sys.modules[__name__], self.type + 'Discount') 

आप सुपर के __init__ इससे पहले कि आप self.type उपयोग करने में सक्षम हो जाएगा कॉल करने के लिए की जरूरत है।

Becareful अपने क्षेत्र बुला typetype के बाद से, यह भी एक अजगर में निर्मित समारोह है, हालांकि आप किसी भी समस्या में नहीं चला सकता है के साथ।

देखें: self.type संदर्भित से पहले http://docs.python.org/library/functions.html#type

+0

धन्यवाद। एक और सवाल, ऑब्जेक्ट गुणों तक पहुंचने से पहले मुझे सुपर __init__ को कॉल करने की आवश्यकता क्यों है? मैंने सोचा कि यह एक अजगर है जो सभी सदस्यों को कन्स्ट्रक्टर में एक्सेस करने योग्य वस्तु में घोषित करता है, न कि सुपर क्लास (मॉडल। डीजेगो से मॉडल)। कैसे? – aambrozkiewicz

+2

ऐसा इसलिए है क्योंकि django.db.models.Model में '__metaclass__ = ModelBase' है। इसका मतलब है कि django नियमित 'प्रकार' के बजाय अपनी मॉडल कक्षा बनाने के लिए' मॉडलबेस 'का उपयोग करता है। मैं अत्यधिक पढ़ने का सुझाव देता हूं: http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python - और एक बार जब आप मेटाक्लास को महारत हासिल कर लेते हैं, तो django स्रोत कोड देखें। –

0

कॉल super(Discount, self).__init__(*args, **kwargs)