vault backup: 2026-05-31 10:03:46
This commit is contained in:
Vendored
+2
-2
File diff suppressed because one or more lines are too long
@@ -87,14 +87,21 @@ Django QuerySet ленивы (вычисляются только при обр
|
||||
- `isnull=True`.
|
||||
|
||||
### Оптимизация запросов
|
||||
- `select_related('field')`: INNER JOIN для ForeignKey и OneToOne.
|
||||
- `prefetch_related('field')`: 2-й запрос для ManyToMany и обратных связей.
|
||||
- **Проблема N+1:** Возникает при обращении к связанным полям в цикле без предварительной подгрузки.
|
||||
- `select_related('field')` — заранее подтягивает связанную запись через `JOIN`. Подходит для `ForeignKey` и `OneToOneField`, когда у объекта есть одна связанная запись.
|
||||
- `prefetch_related('field')` — делает отдельный запрос за связанными объектами и собирает их в Python. Подходит для `ManyToManyField` и обратных связей, где связанных записей может быть много.
|
||||
- **Проблема N+1** — ситуация, когда Django делает один запрос за списком объектов, а потом ещё по одному запросу на каждый объект в цикле.
|
||||
|
||||
Пример: если вывести 100 книг и для каждой обратиться к `book.author`, без оптимизации может получиться 101 запрос. С `select_related('author')` авторы будут загружены сразу.
|
||||
|
||||
### Агрегация и аннотация
|
||||
- `aggregate(Avg('rating'))`: терминальный метод, возвращает словарь.
|
||||
- `annotate(total=Count('entries'))`: добавляет вычисляемое поле к каждому объекту в выборке.
|
||||
- `aggregate(Avg('rating'))` — считает одно итоговое значение по всей выборке: среднее, сумму, минимум, максимум, количество. Возвращает словарь, а не QuerySet.
|
||||
- `annotate(total=Count('entries'))` — добавляет вычисляемое поле к каждому объекту в выборке.
|
||||
|
||||
Пример: `Book.objects.aggregate(Avg('rating'))` вернёт средний рейтинг всех книг. `Author.objects.annotate(total=Count('books'))` добавит каждому автору поле `total` с количеством его книг.
|
||||
|
||||
### Логические условия
|
||||
- `Q-объекты`: Позволяют использовать `OR` (`|`), `AND` (`&`), `NOT` (`~`).
|
||||
- `F-выражения`: Ссылки на поля в БД (атомарные операции без Race Condition).
|
||||
- `Q-объекты` нужны для сложных условий в `filter()`: `OR` (`|`), `AND` (`&`), `NOT` (`~`).
|
||||
- `F-выражения` позволяют сравнивать и изменять поля прямо на стороне БД, не загружая значение в Python.
|
||||
|
||||
Пример `Q`: найти книги, где рейтинг выше 4 или название содержит `Django`.
|
||||
Пример `F`: увеличить счётчик просмотров на 1 прямо в БД: `views = F('views') + 1`.
|
||||
|
||||
Reference in New Issue
Block a user