🐛 Типичные ошибки практикума 10
Ошибки при работе с permissions, dumpdata и Swagger
⚡ Топ-5 ошибок
- Забыть makemigrations после Meta.permissions — разрешение не появится в Admin
- has_permission вместо has_object_permission — object-level проверка не работает
- has_perm без app_label —
has_perm('can_view_statistics')всегда False - loaddata без migrate — таблицы не существуют, ошибка IntegrityError
- drf_yasg не в INSTALLED_APPS — Swagger UI не загружает статику, пустая страница
Ошибка 1: Забыли makemigrations после Meta.permissions
Симптом
Разрешение can_view_statistics не появляется в Django Admin. has_perm() всегда возвращает False, даже для суперпользователя (в некоторых случаях).
Причина
Meta.permissions создаёт новую строку в таблице auth_permission, но только после применения миграций. Если не выполнить makemigrations + migrate — запись не создаётся.
Исправление
python manage.py makemigrations
python manage.py migrate
Ошибка 2: Только has_permission вместо has_object_permission
Симптом
Не-владелец может изменять чужой заказ. Разрешение не защищает конкретные объекты.
Причина
# Неправильно: только has_permission (view-level)
class IsCustomerOrReadOnly(BasePermission):
def has_permission(self, request, view):
return obj.customer == request.user # NameError: obj не определён!
has_permission вызывается до обращения к объекту. Объект obj в этом методе недоступен. Object-level проверка — это has_object_permission.
Исправление
# Правильно: has_object_permission для object-level
class IsCustomerOrReadOnly(BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in ['GET', 'HEAD', 'OPTIONS']:
return True
return obj.customer == request.user
Ошибка 3: has_perm без app_label
Симптом
Эндпоинт статистики всегда возвращает 403, даже если пользователь состоит в группе "Statistic".
Причина
# Неправильно: без app_label
def has_permission(self, request, view):
return request.user.has_perm('can_view_statistics') # False всегда
Django требует полного имени разрешения в формате 'app_label.codename'.
Исправление
# Правильно: с app_label
def has_permission(self, request, view):
return request.user.has_perm('store.can_view_statistics')
Ошибка 4: loaddata без предварительного migrate
Симптом
django.db.utils.OperationalError: no such table: store_order
Причина
После удаления БД (или создания новой) таблицы не существуют. loaddata пытается вставить данные в несуществующие таблицы.
Исправление
# Сначала создать структуру таблиц
python manage.py migrate
# Только потом загружать данные
python manage.py loaddata db_backup.json
Ошибка 5: drf_yasg не в INSTALLED_APPS
Симптом
Swagger UI открывается, но выглядит как пустая страница без стилей. В консоли браузера: 404 на статические файлы.
Причина
Статика (JS, CSS) Swagger UI берётся из пакета через Django staticfiles. Без добавления в INSTALLED_APPS Django не знает об этих файлах.
Исправление
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'drf_yasg', # добавить!
]
Ошибка 6: perform_create не вызывает super()
Симптом
Объект не сохраняется. Нет ошибки, но данные не появляются в БД.
Причина
# Неправильно: вызывает super() вместо serializer.save()
def perform_create(self, serializer):
super().perform_create(serializer)
# customer не передан, значение берётся из запроса
# (или вызывает ошибку если поле обязательное)
Исправление
# Правильно: serializer.save() с дополнительным полем
def perform_create(self, serializer):
serializer.save(customer=self.request.user)
Ошибка 7: ContentType-конфликт при loaddata
Симптом
django.db.utils.IntegrityError: UNIQUE constraint failed: django_content_type.app_label, django_content_type.model
Причина
В дампе включены ContentType-записи. При migrate они уже созданы, и при loaddata возникает конфликт уникальности.
Исправление
# При создании дампа исключить проблемные таблицы:
python manage.py dumpdata \
--exclude auth.permission \
--exclude contenttypes \
--indent=4 > db_backup.json