l'héritage de Django modèle, les modèles de filtrage
-
21-09-2019 - |
Question
Étant donné les modèles suivants: (ne me dérange pas les TextFields il juste pour illustration êtes)
class Base(models.Model):
field1 = models.TextField()
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
class Content(models.Model):
aso_items = models.ManyToManyField('Base')
Selon ces définitions un objet contenu peut être associé à plus d'un objet de base, par exemple. une interview (= objet contenu) peut être lié à un musicien (= objet Enfant1), un filmdirector (= Enfant2), etc.
Maintenant, pour ma question: Est-il possible de filtrer les objets de contenu en fonction du modèle les points sur le terrain de aso_items à? Un exemple: Disons que je voudrais un QuerySet contenant tous les objets de contenu qui sont associés à un objet spécifique de Enfant1, comment puis-je parvenir (par exemple tous les Entretiens associés au musicien Bob Dylan.)?
De plus, si je veux un QuerySet contenant tous les objets de contenu qui sont associés à des objets CHILD1? (Par exemple. Toutes les interviews associées aux musiciens) Comment cela change-t le filtrage?
Merci d'avance ps: Je rencontre quelques problèmes avec l'espace blanc dans l'aperçu, pardonnez-moi
La solution
Vous devriez vérifier la section de la documentation de Django en ce qui concerne l'utilisation related_name
pour les classes de base abstraites. http: //docs.djangoproject. com / fr / dev / sujets / db / modèles / #-être prudent avec-nom lié
Pour citer les documents:
Si vous utilisez le
related_name
attribut sur un ForeignKey ou ManyToManyField, vous devez toujours spécifiez un nom inverse unique pour la champ. Cela devrait provoquer une problème dans les classes de base abstraites, étant donné que les champs de cette classe sont inclus dans chacun de l'enfant classes, avec exactement les mêmes valeurs des attributs (y comprisrelated_name
) à chaque fois.Pour contourner ce problème, lorsque vous utilisent related_name dans un résumé classe de base (seulement), une partie du nom devrait être la chaîne
%(class)s
. Cette est remplacé par le nom inférieur tubée la classe enfant que le champ est utilisé en. Étant donné que chaque classe a un autre nom, chaque nom lié finira étant différent.
En utilisant cette information, je recommande de transférer le champ m2m dans la classe de base:
class Content(models.Model):
# Add remaining fields for Content
pass
class Base(models.Model):
field1 = models.TextField()
items = models.ManyToManyField(Content,related_name="%(class)s_related")
class Meta:
abstract=True
class Child1(Base):
child1_field = models.TextField()
class Child2(Base):
child2_field = models.TextField()
Autres conseils
Apparemment, une relation ForeignKey (ou ManyToMany pour cette matière) avec une classe abstraite est interdite. Je reçois l'erreur suivante: « AssertionError: ForeignKey ne peut pas définir une relation avec classe abstraite Artiest »
.Une solution possible est de définir la classe de base comme non abstraite, mais cela implique que l'on pourrait instancier modèles de la classe de base. Ce qui est pas le comportement que je veux. (Après tout, ce fut une classe abstraite) Est-ce que quelqu'un se accross le même problème comment avez-vous le résoudre? Toute solution de rechange?
Jetez un oeil à http://www.djangoproject.com/documentation/models/ generic_relations / qui passe par les relations génériques. Votre modèle de contenu correspondrait à leur modèle TaggedItem et votre modèle de base correspondrait à leur animal / légumes / modèle minéral (à l'extension Enfant1 et Enfant2).
Obtenir tous les objets de contenu pour un seul enfant serait (en supposant que vous définissez le contenu à l'intérieur GenericRelation à base):
child_contents = childObject.contents.all()
Et pour tous les objets de contenu pour un modèle:
ctype = ContentType.objects.get_for_model(Child1)
all_child_contents = Content.objects.filter(content_type=ctype)