1. DoesNotExist — запись не найдена
Ошибка
# Если книги с таким названием нет — упадёт с исключением
book = Book.objects.get(title="Несуществующая книга")
# → Book.DoesNotExist: Book matching query does not exist.
Решение
# Вариант 1 — try/except
try:
book = Book.objects.get(title="Несуществующая книга")
except Book.DoesNotExist:
book = None
# Вариант 2 — filter().first() (None если не найдено)
book = Book.objects.filter(title="Несуществующая книга").first()
# Вариант 3 — get_or_create()
book, created = Book.objects.get_or_create(
title="Новая книга",
defaults={"author": "Unknown", "published_date": "2024-01-01"}
)
2. MultipleObjectsReturned — несколько записей
Ошибка
# Если несколько книг с author="Orwell" — ошибка
book = Book.objects.get(author="Orwell")
# → Book.MultipleObjectsReturned
Решение
# Уточнить условие по уникальному полю
book = Book.objects.get(title="1984", author="Orwell")
# Или — если нужна одна, используйте filter()
book = Book.objects.filter(author="Orwell").first()
# Или — обработать все
books = Book.objects.filter(author="Orwell")
for book in books:
print(book.title)
3. FieldError — несуществующее поле
Ошибка
# Опечатка в имени поля
books = Book.objects.filter(titl__icontains="gatsby")
# → FieldError: Cannot resolve keyword 'titl' into field.
# Choices are: author, id, is_bestseller, price, published_date, title
Решение
# Правильное имя поля
books = Book.objects.filter(title__icontains="gatsby")
# Если не помните поля — проверьте модель
print([f.name for f in Book._meta.get_fields()])
4. Забыли двойное подчёркивание __
Ошибка
# Одно подчёркивание — Django воспримет как имя поля
books = Book.objects.filter(title_icontains="gatsby")
# → FieldError: Cannot resolve keyword 'title_icontains'
Решение
# Два подчёркивания — разделитель поле__lookup
books = Book.objects.filter(title__icontains="gatsby")
5. Неправильный тип значения в lookup
Ошибка
# isnull ожидает True/False, не строку
books = Book.objects.filter(price__isnull="true")
# Работает, но "true" как строка — не то, что ожидается
Решение
# Использовать булевые значения
books = Book.objects.filter(price__isnull=True)
books = Book.objects.filter(price__isnull=False)
6. N+1 проблема при обращении к связанным объектам
Ошибка
# Если Author — отдельная модель через FK
# Каждая итерация делает отдельный SQL-запрос
books = Book.objects.all()
for book in books:
print(book.author_obj.name) # N отдельных запросов SELECT author
Решение
# select_related() — JOIN в одном запросе (FK / OneToOne)
books = Book.objects.select_related('author_obj').all()
for book in books:
print(book.author_obj.name) # данные уже загружены
# prefetch_related() — для ManyToMany или обратных FK
books = Book.objects.prefetch_related('tags').all()
⚠️ Проверить по документации:
select_related() и prefetch_related() — ключевые инструменты оптимизации ORM. Подробнее в уроках по advanced ORM.
7. Использование filter() как get() без проверки количества
Ошибка
# filter() возвращает QuerySet, а не объект
book = Book.objects.filter(title="1984")
print(book.title) # AttributeError: 'QuerySet' object has no attribute 'title'
Решение
# Если нужна одна запись — get() или filter().first()
book = Book.objects.get(title="1984") # ровно одна
# или
book = Book.objects.filter(title="1984").first() # первая или None
print(book.title)
8. Изменение объекта без save()
Ошибка
# Изменили атрибут, но не вызвали save() — изменение не сохранится в БД
book = Book.objects.get(id=1)
book.title = "Новое название"
# Забыли book.save() — в БД всё по-прежнему
Решение
book = Book.objects.get(id=1)
book.title = "Новое название"
book.save() # или book.save(update_fields=['title']) — экономнее
# Массовое обновление через QuerySet.update() — save() не нужен
Book.objects.filter(id=1).update(title="Новое название")