2

Disons que j'ai la structure du modèle suivant:django annoter modèles avec une valeur globale basée sur requête

Parent(): 

Child(): 
parent = ForeignKey(Parent) 

GrandChild(): 
child = ForeignKey(Child) 
state = BooleanField() 
num = FloatField() 

Je suis en train de le parent ViewSet, récupérer les éléments suivants:

  1. Le Nombre d'enfants.
  2. Somme des champs 'num' lorsque 'state' a la valeur True.

je peux faire ce qui suit:

queryset = Parent.objects\ 
    .annotate(child_count=Count('child'))\ 
    .annotate(sum_total=Sum('child__grandchild__num')) 

Cela me donne (1) mais au lieu de (2) il me donne la somme pour TOUS les petits-enfants. Comment puis-je filtrer correctement les petits-enfants tout en m'assurant que tous les objets Parent sont toujours dans le QuerySet?

Répondre

1

Essayez d'utiliser le filtre avant la annoter

queryset = Parent.objects.filter(child__grandchild__state=True')\ 
    .annotate(child_count=Count('child'))\ 
    .annotate(sum_total=Sum('child__grandchild__num')) 
+0

Cela fonctionnerait, mais je dois m'assurer que j'ai tous les objets parents. Désolé, je vais éditer la question initiale. – Eric

+0

@Eric Vous obtiendrez le jeu de requête de l'objet parent à partir de ceci. –

+0

Que faire si le parent particulier n'a pas GrandChild? – Eric

0

Quelle version de django utilisez-vous? Vous pouvez également utiliser la sous-requête si la version est prise en charge.

Parent.objects 
.annotate(child_count=Count('child')) 
.annotate(
    grandchild_count_for_state_true=Subquery(
     GrandChild.objects.filter(
      state=True, 
      child=OuterRef('pk') 
     ).values('parent') 
     .annotate(cnt=Sum('child__grandchild__num')) 
     .values('cnt'), 
     num=models.IntegerField() 
    ) 
) 

Vous pouvez optimiser cela via une requête d'agrégation.

+0

Une sous-requête peut être la route que je dois suivre mais votre réponse est incorrecte. 1. Je cherche une somme, pas un compte. 2. Je n'ai pas de modèle nommé 'Evénement'. 3. Le champ 'num' est un FloatField, pas un IntegerField. – Eric