python - manager - django queryset
Django Model Mixins: hereda de models.Model o de object? (4)
Esta es una pregunta sobre Python Mixins que podría ser útil en general. Solo estoy usando modelos de Django ya que ese es el caso de uso con el que estoy más familiarizado.
¿Debe una mezcla heredar de la clase está diseñada para mezclarse con o desde ''objeto''?
Ejemplos por código, ¿qué es más correcto o mejor, o mejor dependiendo de lo que quiere lograr?
Esta
class TaggingMixin(models.Model):
tag = models.ForeignKey(Tag)
class Meta:
abstract = True
class MyModel(models.Model, TaggingMixin):
title = models.CharField(max_length=100)
O esto:
class TaggingMixin(object):
tag = models.ForeignKey(Tag)
class Meta:
abstract = True
class MyModel(models.Model, TaggingMixin):
title = models.CharField(max_length=100)
Creo que heredar de un objeto es el camino correcto. Pero estoy viendo ejemplos del primer caso en toda la red ...
EDITAR: He trasladado mi pregunta de seguimiento a otra pregunta: Modelos abstractos de Django versus Python mixins simples versus Python ABCs
Cuando heredas del objeto simple de Python, South no crea una migración, por lo que no puedes usar este enfoque
Django hace un montón de meta mágica cuando se trata de sus clases modelo, por lo que desafortunadamente el enfoque habitual de mixins, como se sugiere en la respuesta de Daniel Roseman, donde heredan del object
, no funciona bien en el universo de Django.
La forma correcta de estructurar sus mixins, utilizando el ejemplo proporcionado, sería:
class TaggingMixin(models.Model):
tag = models.ForeignKey(Tag)
class Meta:
abstract = True
class MyModel(TaggingMixin):
title = models.CharField(max_length=100)
Los puntos importantes aquí son:
- Mixins hereda de
model.Model
pero está configurado como una clase abstracta. - Debido a que mixins hereda de
model.Model
, su modelo real no debería heredar de él. Si lo hace, esto podría desencadenar una excepción consistente de orden de resolución de método.
Esto parece un trabajo para un modelo abstracto .
EDITAR:
Esos no son mixins per se. O más bien, no necesitan serlo. Puede derivar de un modelo abstracto directamente.
Yo recomendaría que herede del object
. De esta forma, puede asegurarse de que solo proporcione los métodos y atributos que realmente define explícitamente.
Además, siempre debes asegurarte de poner primero la clase mixin al definir tu clase concreta. Las reglas de resolución de Python significan que las superclases se buscan por orden de definición en la declaración de clase, y la resolución se detiene cuando se encuentra un atributo coincidente. Entonces, si tu mixin define un método que también está definido por la superclase principal, no se encontrará tu método de mixin.