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

Était-ce utile?

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 compris   related_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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top