🐛 Типичные ошибки
⚡ Топ-5 ошибок
- Неправильный путь в INSTALLED_APPS:
'tasks'вместо'apps.tasks.apps.TasksConfig' - Нет
__init__.pyв модуле models/: Django не видит классы моделей - Забыт
make_aware(): сравнение naive datetime с aware → RuntimeWarning / TypeError - Enum
choicesвызывается без скобок:choices=Statuses.choices(правильно) vschoices=Statuses.choices()(ошибка при передаче) - Файл через
request.dataвместоrequest.FILES: файл не будет доступен
1. Неверный путь регистрации приложения в INSTALLED_APPS
Проблема: Приложение не найдено Django или миграции не создаются.
# НЕПРАВИЛЬНО — просто имя
INSTALLED_APPS = ['tasks', 'projects']
# ПРАВИЛЬНО — полный путь с AppConfig
INSTALLED_APPS = [
'apps.tasks.apps.TasksConfig',
'apps.projects.apps.ProjectsConfig',
]
Почему: При использовании модуля apps/ Django должен знать полный путь к классу конфигурации приложения.
2. Отсутствие __init__.py в модуле models/
Проблема: ImportError: cannot import name 'Tag' from 'apps.tasks.models'
# НЕПРАВИЛЬНО — нет экспорта
# apps/tasks/models/__init__.py пустой
# ПРАВИЛЬНО — явный экспорт классов
# apps/tasks/models/__init__.py
from apps.tasks.models.tag import Tag
from apps.tasks.models.task import Task
Аналогично для apps/projects/models/__init__.py.
3. Naive datetime при фильтрации по датам
Проблема: RuntimeWarning: DateTimeField received a naive datetime или TypeError: can't compare offset-naive and offset-aware datetimes
# НЕПРАВИЛЬНО
date_from = datetime.strptime(date_from, '%Y-%m-%d')
# Объект без timezone (naive)
# ПРАВИЛЬНО
from django.utils import timezone
date_from = timezone.make_aware(
datetime.strptime(date_from, '%Y-%m-%d')
)
# Объект с timezone (aware)
Django хранит DateTimeField с учётом USE_TZ = True. Все сравнения должны быть между aware datetime.
4. Неверное обращение к Enum choices в модели
Проблема: Поле принимает неожиданные значения или выдаёт ошибку при миграции.
# НЕПРАВИЛЬНО — choices передаётся как результат вызова
status = models.CharField(
choices=Statuses.choices(), # вернёт список, не callable
default=Statuses.NEW # это Enum-объект, не строка
)
# ПРАВИЛЬНО — ссылка на classmethod без вызова
status = models.CharField(
max_length=15,
choices=Statuses.choices, # передаём ссылку на classmethod
default=Statuses.NEW # Django вызовет .value автоматически
)
5. Файл через request.data вместо request.FILES
Проблема: KeyError: 'file' или файл получается как строка вместо InMemoryUploadedFile.
# НЕПРАВИЛЬНО
file_content = request.data["file"]
# ПРАВИЛЬНО
file_content = request.FILES["file"]
# Для текстовых полей — request.data
project_id = request.data["project_id"]
Файлы при multipart/form-data попадают в request.FILES, а текстовые поля — в request.data.
6. Создание приложения не в папке apps/
Проблема: Приложение создаётся в корне проекта вместо модуля apps/.
# НЕПРАВИЛЬНО — запуск из корня проекта
python manage.py startapp tasks
# Создаст apps/tasks в корне, а не в apps/
# ПРАВИЛЬНО — запуск из папки apps/
cd apps
python ../manage.py startapp tasks
# Создаст apps/tasks
7. Отсутствие content_type multipart в POST-запросе загрузки файла
Проблема: Файл не загружается, request.FILES пустой.
# Postman: при загрузке файла выбрать Body → form-data
# и установить тип поля 'file' как 'File', а не 'Text'
# curl-аналог:
curl -X POST http://localhost:8000/api/v1/projects/files/ \
-F "file_name=report.pdf" \
-F "project_id=1" \
-F "file=@/path/to/report.pdf"