2 votes

django annote les modèles avec une valeur agrégée basée sur une requête

Disons que j'ai la structure de modèle suivante :

Parent():

Child():
parent = ForeignKey(Parent)

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

J'essaie de faire en sorte que les parents ViewSet récupérer les éléments suivants :

  1. Le nombre d'enfants.
  2. La SOMME des champs 'num' lorsque 'state' est vrai.

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), cela me donne la SOMME pour TOUS les petits-enfants. Comment puis-je filtrer les petits-enfants de manière appropriée tout en m'assurant que j'ai tous les éléments de la base de données. Parent toujours dans le QuerySet ?

1voto

Arpit Solanki Points 5230

Essayez d'utiliser le filtre avant l'annotation

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

0voto

Patrick Points 132

Quelle version de django utilisez-vous ? Vous pouvez également utiliser une 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 grâce à une requête d'agrégation.

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