web-dev-qa-db-fra.com

Comment grouper par AND et agréger avec Django

J'ai une requête assez simple que je voudrais faire via l'ORM, mais je ne peux pas comprendre cela ..

J'ai trois modèles:

Emplacement (un lieu), Attribut (un attribut qu'un emplacement peut avoir) et Notation (un modèle M2M "à" qui contient également un champ de score)

Je veux choisir des attributs importants et pouvoir classer mes emplacements en fonction de ces attributs - c’est-à-dire un score total plus élevé que tous les attributs sélectionnés = meilleur.

Je peux utiliser le code SQL suivant pour obtenir ce que je veux:

select location_id, sum(score) 
    from locations_rating 
    where attribute_id in (1,2,3) 
    group by location_id order by sum desc;

qui retourne

 location_id | sum 
-------------+-----
          21 |  12
           3 |  11

Le plus proche que je peux obtenir avec l'ORM est:

Rating.objects.filter(
    attribute__in=attributes).annotate(
    acount=Count('location')).aggregate(Sum('score'))

Qui retourne

{'score__sum': 23}

c'est-à-dire la somme de tous, non groupés par lieu.

Tout moyen de contourner ça? Je pourrais exécuter le SQL manuellement, mais préférerais passer par l'ORM pour que les choses restent cohérentes.

Merci

70
Guy Bowden

Essaye ça:

Rating.objects.filter(attribute__in=attributes) \
    .values('location') \
    .annotate(score = Sum('score')) \
    .order_by('-score')
121
Aamir Adnan

Pouvez-vous essayer ceci.

Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).