Il modello Discount
descrive i campi comuni per tutti i tipi di sconti nel sistema. Ho alcuni modelli di proxy che descrivono algoritmi concreti per il totale della culcolazione. La classe Discount
di base ha un campo membro denominato type
, che è una stringa che identifica il suo tipo e la relativa classe.polimorfismo del modello django con ereditarietà del proxy
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
Ma continuo a ricevere l'eccezione di AttributeError che dice che self non ha tipo. Come risolvere questo problema o esiste un altro modo per raggiungere questo obiettivo?
Grazie. Ancora una domanda, perché devo chiamare super __init__ prima di accedere alle proprietà degli oggetti? Ho pensato che fosse un python che rende tutti i membri dichiarati in oggetto accessibili nel costruttore, non in super classe (models.Model di Django). Come mai? – aambrozkiewicz
Questo perché django.db.models.Model ha '__metaclass__ = ModelBase'. Ciò significa che django usa 'ModelBase' per creare la tua classe Model invece del normale' type'. Consiglio vivamente di leggere: http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python - e una volta che hai imparato le metaclassi, guarda il codice sorgente di django. –