Mi modelo Discount
describe los campos comunes para todos los tipos de descuentos en el sistema. Tengo algunos modelos proxy que describen el algoritmo concreto para calcular el total. La clase base Discount
tiene un campo de miembro denominado type
, que es una cadena que identifica su tipo y su clase relacionada.polimorfismo modelo django con herencia 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
Pero sigo obteniendo una excepción de AttributeError diciendo que uno no tiene el tipo. ¿Cómo solucionar esto o hay otra forma de lograr esto?
Gracias. Una pregunta más, ¿por qué debo llamar a super__init__ antes de acceder a las propiedades de los objetos? Pensé que es una pitón que hace que todos los miembros declarados en el objeto sean accesibles en el constructor, no en la superclase (modelos.Modelo de Django). ¿Cómo? – aambrozkiewicz
Esto es porque django.db.models.Model tiene '__metaclass__ = ModelBase'. Esto significa que django usa 'ModelBase' para crear su clase de modelo en lugar del' tipo' normal. Recomiendo leer: http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python - y una vez que hayas dominado las metaclases, mira el código fuente de django. –