🐛 Типичные ошибки

⚡ Топ-5 ошибок

  1. ForeignKey без on_deleteTypeError
  2. Перепутать null и blank → форма/БД ведут себя неожиданно
  3. Забыть makemigrations после изменения модели → БД не обновляется
  4. NullBooleanFieldImproperlyConfigured в Django 5.x
  5. Приложение не в INSTALLED_APPSmakemigrations не видит модели

Ошибка 1: ForeignKey без on_delete

Симптом

TypeError: __init__() missing 1 required positional argument: 'on_delete'

Причина

# Неверно — on_delete не указан (работало только до Django 2.0)
author = models.ForeignKey(Author)

Решение

# Верно — on_delete обязателен в Django 2.0+
author = models.ForeignKey(Author, on_delete=models.CASCADE)

# Другие варианты:
author = models.ForeignKey(Author, on_delete=models.PROTECT)
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)

Ошибка 2: Путаница null и blank

Симптом

Форма принимает пустое поле, но в БД сохраняется пустая строка вместо NULL (или наоборот). Или модель сохраняется, но форма требует значение несмотря на null=True.

Причина

# null=True влияет ТОЛЬКО на базу данных
# blank=True влияет ТОЛЬКО на форму Django

# Неверно для строкового поля: null без blank не делает поле необязательным в формах
description = models.TextField(null=True)  # форма всё равно требует значение

Решение

# Для строковых полей, которые не обязательны:
description = models.TextField(blank=True, default='')
# blank=True — форма не требует значение
# default='' — в БД сохраняется пустая строка (не NULL)

# Если нужен настоящий NULL (редко нужен для строк):
description = models.TextField(null=True, blank=True)

# Для нестроковых (DateField, ForeignKey) — null=True нормально:
birthday = models.DateField(null=True, blank=True)
Правило: для строковых полей (CharField, TextField) предпочитайте blank=True без null=True. Пустая строка лучше NULL — нет нужды проверять два состояния «пусто».

Ошибка 3: Изменил модель, но не создал миграцию

Симптом

# В shell или при обращении к новому полю:
django.db.utils.OperationalError: table myapp_book has no column named rating

Причина

Добавили поле в models.py, но не выполнили makemigrations + migrate. Модель Python изменилась, а таблица БД — нет.

Решение

# После любого изменения models.py обязательно:
python manage.py makemigrations    # 1. Создать файл миграции
python manage.py migrate           # 2. Применить к БД

# Проверить статус миграций:
python manage.py showmigrations

Ошибка 4: NullBooleanField в Django 5.x

Симптом

django.core.exceptions.ImproperlyConfigured: NullBooleanField is removed in Django 5.0

Причина

# Устаревшее поле из старой версии Django
is_verified = models.NullBooleanField()  # Удалено в Django 5.x

Решение

# Современная замена:
is_verified = models.BooleanField(null=True, blank=True)

Ошибка 5: Приложение не добавлено в INSTALLED_APPS

Симптом

# makemigrations не видит изменения в моделях
# Или нет папки migrations/ в приложении

Причина

# settings.py — приложение myapp не добавлено
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    # 'myapp',  ← забыли добавить
]

Решение

# settings.py — добавить своё приложение
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'myapp',   # ← добавить сюда
]

Ошибка 6: CharField без max_length

Симптом

django.core.exceptions.FieldError: CharField requires a 'max_length' argument

Причина

# CharField требует max_length
name = models.CharField()  # ошибка

Решение

name = models.CharField(max_length=200)  # max_length обязателен

Ошибка 7: DecimalField без max_digits и decimal_places

Симптом

django.core.exceptions.FieldError: DecimalField requires 'max_digits' and 'decimal_places' arguments

Причина

price = models.DecimalField()  # не хватает обязательных параметров

Решение

price = models.DecimalField(max_digits=10, decimal_places=2)
# max_digits — всего цифр (включая после запятой)
# decimal_places — цифр после запятой

Ошибка 8: IntegrityError при нарушении unique

Симптом

django.db.utils.IntegrityError: UNIQUE constraint failed: myapp_book.isbn

Причина

Попытка сохранить объект с дублирующимся значением поля с unique=True.

Решение

from django.db import IntegrityError

try:
    book = Book(isbn='978-3-16-148410-0', title='Новая книга')
    book.save()
except IntegrityError:
    print("Книга с таким ISBN уже существует")

# Или проверить перед сохранением:
if not Book.objects.filter(isbn='978-3-16-148410-0').exists():
    book.save()