web-dev-qa-db-fra.com

Comment exécuter un GROUP BY ... COUNT ou SUM dans Django ORM?

Prologue:

C'est une question qui se pose souvent dans SO:

J'ai composé un exemple sur SO Documentation mais puisque la documentation sera fermée le 8 août 2017, je suivrai la suggestion de cette méta-réponse largement votée et discutée = et transformer mon exemple en un message auto-répondu.

Bien sûr, je serais plus qu'heureux de voir une approche différente aussi !!


Question:

Supposons le modèle:

class Books(models.Model):
    title  = models.CharField()
    author = models.CharField()
    price = models.FloatField()

Comment puis-je effectuer les requêtes suivantes sur ce modèle en utilisant Django ORM:

  • GROUP BY ... COUNT:

    SELECT author, COUNT(author) AS count
    FROM myapp_books GROUP BY author
    
  • GROUP BY ... SUM:

    SELECT author,  SUM (price) AS total_price
    FROM myapp_books GROUP BY author
    
11
John Moutafis

Nous pouvons effectuer un GROUP BY ... COUNT Ou un GROUP BY ... SUM Requêtes SQL équivalentes sur Django ORM, avec l'utilisation de annotate() , values() , les méthodes Count et Sum du Django.db.models respectueusement et éventuellement les order_by() méthode:

  • GROUP BY ... COUNT:

    from Django.db.models import Count
    
    result = Books.objects.values('author')
                          .order_by('author')
                          .annotate(count=Count('author'))
    

    Le résultat contient maintenant un dictionnaire avec deux clés: author et count:

      author    | count
    ------------|-------
     OneAuthor  |   5
    OtherAuthor |   2
       ...      |  ...
    
  • GROUP BY ... SUM:

    from Django.db.models import Sum
    
     result = Books.objects.values('author')
                           .order_by('author')
                           .annotate(total_price=Sum('price'))
    

    Le résultat contient maintenant un dictionnaire avec deux colonnes: author et total_price:

      author    | total_price
    ------------|-------------
     OneAuthor  |    100.35
    OtherAuthor |     50.00
        ...     |      ...
    
17
John Moutafis