Django ORM и Group By

Формирование сложных запросов с использованием Django ORM без написания SQL кода может быть не всегда очевидной вещью. Например, подсчет количества одинаковых записей в базе, отфильтрованных согласно определенному критерию. В SQL это решается просто с использованием GROUP BY и COUNT(). В Django ORM для этого имеются агрегации.

Положим у нас есть модель для хранения запросов, по которым на сайт попадают пользователи с поисковиков:

from django.db import models

class SearchReferer(models.Model):
    search_query = models.CharField(max_length=255)
    page_url = models.CharField(max_length=255)
    created_at = models.DateTimeField(add_now_auto=True)

Задача подсчитать статистику поисковых запросов для определенной страницы, т.е. нужно получить аналог запроса:

SELECT search_query, COUNT(*) AS query_count
FROM search_referers_searchreferer
WHERE page_url = "/"
GROUP BY search_query
ORDER BY query_count DESC

В Django ORM это соответствует такой конструкции:

from django.db.models import Count
from search_referers.models import SearchReferer

SearchReferer.objects.filter(page_url="/")\
             .values("search_query")\
             .annotate(query_count=Count("search_query"))\
             .order_by("-query_count")

В результате получаем список хешей ({"search_query": "", "query_count": 1}), отсортированных по популярности.

 
comments powered by Disqus