Какие методы решают проблему N+1 при доступе к связанным таблицам в Django
Python
Middle
Без компании
Какие методы решают проблему N+1 при доступе к связанным таблицам в Django
Ответы
В Django для решения проблемы N+1 запросов при работе с связанными моделями есть несколько подходов:
- **select_related()** - для ForeignKey и OneToOneField. Выполняет JOIN в SQL-запросе:
```
books = Book.objects.select_related('author').all()
```
- **prefetch_related()** - для ManyToManyField и обратных ForeignKey. Делает отдельный запрос для связи:
```
authors = Author.objects.prefetch_related('books').all()
```
- **Prefetch()** - для сложных префетчей с фильтрацией:
```
from django.db.models import Prefetch
active_books = Book.objects.filter(active=True)
authors = Author.objects.prefetch_related(
Prefetch('books', queryset=active_books)
)
```
- **only()/defer()** - для выбора только нужных полей:
```
Book.objects.select_related('author').only('title', 'author__name')
```
- **annotate()** - для агрегации без дополнительных запросов:
```
from django.db.models import Count
Author.objects.annotate(book_count=Count('books'))
```