3 votes

Django obtient un objet enfant par le biais du parent

J'ai essayé d'accéder à l'objet enfant, par l'intermédiaire de l'objet parent, car je veux effectuer des opérations différentes selon le type de l'objet. Voici ce que j'ai :

#models.py
class A(models.Model):
    ...

class B(A):
    field1 = models.CharField(...)
    ...

class C(A):
    field2 = models.IntegerField(...)

Je pourrais exécuter 2 boucles for et accomplir ce que je veux :

for obj in B.objects.all():
    if field1 == 'something':
        do some operation

for obj in C.objects.all():
    if field2 == 5:
        do some other operation

Mais je me demandais s'il n'était pas possible de faire cela avec une seule boucle for et d'accéder à l'enfant par le biais du parent ?

for obj in A.objects.all():
    if obj.b and obj.b.field1 == 'something':
        do some operation
    elif obj.c and obj.c.field2 == 5:
        do some other operation

Je pensais aussi que select_related peut faire l'affaire, mais il est dit que cela ne fonctionne que pour ForeignKey .

De plus, j'espérais pouvoir le faire sans utiliser d'autres applications telles que django-model-utils o django-polymorphe parce que j'ai l'impression qu'il devrait y avoir une simple opération de requête pour faire cela.

5voto

Ozgur Akcali Points 158

Vous pouvez accéder à un objet enfant à partir de l'objet parent comme vous l'avez fait dans la boucle for finale, mais vous devez également vérifier si l'enfant existe pour le parent comme ceci :

for obj in A.objects.all():
    try:
        if obj.b.field1 == 'something':
            do some operation
    except ObjectDoesNotExist:
        # obj does not have a child of class B

    try:
        if obj.c.field2 == 5:
            do some other operation
    except ObjectDoesNotExist:
        # obj does not have a child of class C

Vous pouvez également les combiner en une seule requête à l'aide d'objets Q :

A.objects.filter(Q(b__isnull=False, b__field1='something') | Q(c__isnull=False, c__field2=5))

Cela renverrait des objets de la classe A

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X