Поймал себя на долгих запросах в pet и начал материться на «медленный сервер». Секунды ожидания, обновление страницы — и чувство, что я что-то делаю не так, а чего — не знаю. Потом включил сводку запросов и увидел: страница выполняла 120 запросов, хотя данных — 30 строк. Стыдно и понятно одновременно.
Нейтрально: «запрос в цикле» — классическая ошибка: на каждый элемент выборки Django ходит в базу за связанной записью. select_related собирает связь одним JOIN и кладёт её рядом.
# было: 1 + N запросов
items = Item.objects.all()
for i in items:
print(i.category.name) # 1 запрос на каждую строку
# стало: N в один
items = Item.objects.select_related("category")
for i in items:
print(i.category.name)
Тридцать строк превратились из 31 запроса в 2. Что я почувствовал — счастливое облегчение после тупого застревания. Не «крутой трюк», а обычное знание, которого мне не хватало. Потратил полдня на поиск, а оно было в двух строках.