Ответ
Отслеживание SQL-запросов в Django — ключевая задача для оптимизации производительности. Вот основные подходы, отладочные и программные.
1. Django Debug Toolbar (для разработки)
Это самый популярный и наглядный способ. django-debug-toolbar встраивает в страницу панель с детальной информацией о запросе, включая все выполненные SQL-запросы, их количество и время выполнения.
Установка и настройка в settings.py:
# pip install django-debug-toolbar
INSTALLED_APPS = [
# ...
'debug_toolbar',
]
MIDDLEWARE = [
# ...
'debug_toolbar.middleware.DebugToolbarMiddleware',
]
# IP-адреса, с которых будет видна панель
INTERNAL_IPS = [
'127.0.0.1',
]
2. Логирование в консоль
Django может выводить все SQL-запросы в консоль через стандартный механизм логирования. Это полезно при выполнении management-команд или в окружениях, где нельзя использовать Debug Toolbar.
Настройка в settings.py:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
},
},
}
3. Программный доступ через connection.queries
В режиме DEBUG = True Django сохраняет все запросы в списке django.db.connection.queries. Это позволяет анализировать их программно, например, в тестах или кастомном middleware для сбора метрик.
Пример в views.py или тестах:
from django.db import connection
from django.conf import settings
def my_view(request):
# ... ваш код, выполняющий запросы к БД ...
if settings.DEBUG:
query_count = len(connection.queries)
print(f"Выполнено запросов: {query_count}")
for query in connection.queries:
print(f"[{query['time']}с] {query['sql']}")
# ... Ответ 18+ 🔞
Ах ты ж, разработчик, подойди сюда, я тебе сейчас такую штуку расскажу про SQL-запросы в Django, что ты обоссаешься со смеху! Ну, точнее, не со смеху, а с удивления, пиздец, насколько всё просто, если знать, куда смотреть. Сидишь ты, значит, на проекте, а он тормозит, как черепаха в сиропе, и ты думаешь: «Ну что за хуйня, блядь? Кто тут столько запросов навешал?». А оказывается, это ты сам, распиздяй, в цикле ORM-запросы гоняешь! Ну ладно, слушай сюда, как это дело отслеживать.
1. Django Debug Toolbar — твой лучший друг в разработке, ёпта!
Это такая панелька, которая прилипает к правому краю браузера и показывает тебе всю подноготную. Сколько запросов, какие именно, сколько времени каждый жрал — всё, как на духу. Установить — раз плюнуть.
# pip install django-debug-toolbar, блядь, не забудь!
INSTALLED_APPS = [
# ... остальные приложения ...
'debug_toolbar', # воткнул и забыл
]
MIDDLEWARE = [
# ... другое middleware ...
'debug_toolbar.middleware.DebugToolbarMiddleware', # вот это вот важно, сука, не перепутай порядок!
]
# А это чтобы панель только у тебя светилась, а не у всех пользователей, а то они охуеют
INTERNAL_IPS = [
'127.0.0.1',
]
Вот, поставил, запустил сервер — и видишь на каждой странице эту панель. Нажал на SQL — и тебе вываливается список всех запросов. А если какой-то запрос повторяется, как мантра, сто пятьсот раз — сразу видно, где ты, мудак, накосячил с N+1 проблемой. Просто красота, в рот меня чих-пых!
2. Логирование в консоль — для тех, кто любит по-старинке
А бывает, что Debug Toolbar не встаёт — например, в API или когда команды management-ские гоняешь. Ну или просто неохота в браузер тыкать. Тогда можно настроить логирование, чтобы все SQL-запросы летели прямо в консоль, как из пулемёта.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': { # Вот этот логгер, блядь, ключевой!
'handlers': ['console'],
'level': 'DEBUG', # Выставляем DEBUG, чтобы все запросы показывал
},
},
}
Добавил это в settings.py — и всё, теперь при каждом запросе в консоль сыпется куча строк с SQL. Увидишь там что-нибудь вроде SELECT * FROM auth_user WHERE id = 1 — и сразу поймёшь, кто виноват. Главное — не охуеть от количества, если накосячил.
3. Программный доступ — для крутых перцев, которые хотят всё контролировать
А вот это уже для тех, кто любит ковыряться в кишках. В режиме DEBUG = True Django копит все запросы в специальном списке django.db.connection.queries. Можешь достать их оттуда и сделать что хочешь — например, посчитать, сколько их там наворотилось, или в тестах проверять, не наделал ли ты лишнего.
from django.db import connection
from django.conf import settings
def my_view(request):
# ... тут твой код, который наверняка делает кучу запросов ...
if settings.DEBUG: # На всякий случай проверяем, что мы в отладке, а то на проде ёбнемся
query_count = len(connection.queries)
print(f"Выполнено запросов: {query_count}") # Овердохуища, Карл!
for query in connection.queries:
print(f"[{query['time']}с] {query['sql']}") # Время и сам запрос — всё как есть
# ...
Вот так, блядь, взял и вывел. Увидишь, что запросов, как говна за баней, — и сразу бежишь оптимизировать. Может, индексы добавить, а может, select_related или prefetch_related прикрутить. В общем, дело за тобой.
Короче, выбирай способ по душе. Лично я за Debug Toolbar, потому что он нагляден, как хуй в бане. Но если нужно что-то автоматизировать — бери логирование или connection.queries. Главное — не игнорируй эти инструменты, а то потом будешь сидеть и думать: «Ну почему же оно так медленно, ёпта?». А потому что сам виноват, распиздяй!