📖 Теория: Auth и Permissions в DRF
Краткий справочный контекст для практикума 10
⚡ Ключевые концепции
- request.user — объект текущего пользователя, доступен в любом представлении DRF
- perform_create(serializer) — хук сохранения объекта, позволяет добавить
request.userк данным - get_queryset() — переопределение для фильтрации объектов по текущему пользователю
- BasePermission — базовый класс для кастомных разрешений; методы
has_permissionиhas_object_permission - Meta.permissions — пользовательские разрешения Django, регистрируются через миграции
- dumpdata / loaddata — сериализация и восстановление данных БД
- drf-spectacular — библиотека для генерации OpenAPI 3 схемы, Swagger UI и ReDoc
1. Извлечение пользователя из запроса
В DRF объект текущего пользователя всегда доступен через self.request.user внутри представления. Это позволяет автоматически привязывать создаваемые объекты к аутентифицированному пользователю.
perform_create — авто-привязка при создании
Метод perform_create(serializer) вызывается при успешной валидации данных перед сохранением. Его переопределение — стандартный способ добавить поле, недоступное пользователю напрямую:
def perform_create(self, serializer):
serializer.save(customer=self.request.user)
Значение customer=self.request.user передаётся в serializer.save() и переопределяет данные из запроса. Пользователь не может подставить чужой customer.
get_queryset — фильтрация объектов по владельцу
Переопределение get_queryset() ограничивает набор объектов только теми, что принадлежат текущему пользователю:
def get_queryset(self):
return Order.objects.filter(customer=self.request.user)
Это принципиально важно с точки зрения безопасности: без фильтрации пользователь мог бы запросить заказы других пользователей по ID.
2. Кастомные классы разрешений
DRF позволяет создавать собственные классы разрешений, наследуясь от BasePermission. Два ключевых метода:
- has_permission(request, view) — проверяется до обращения к объекту (view-level)
- has_object_permission(request, view, obj) — проверяется при доступе к конкретному объекту (object-level)
has_object_permission вызывается только если has_permission вернул True. Если переопределить только has_object_permission, то для list-операций проверка объектного уровня не выполняется.
Паттерн IsOwnerOrReadOnly
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. Пользовательские разрешения (Meta.permissions)
Django позволяет добавлять произвольные разрешения к модели через class Meta:
class Order(models.Model):
class Meta:
permissions = [
("can_view_statistics", "Can view statistics"),
]
После makemigrations и migrate разрешение появляется в Django Admin. Проверка в коде:
request.user.has_perm('store.can_view_statistics')
Строка состоит из: 'app_label.codename' — название приложения и кодовое имя разрешения.
4. Управление базой данных: dumpdata и loaddata
Django предоставляет команды для резервного копирования и восстановления данных:
Создание дампа
python manage.py dumpdata --indent=4 > db_backup.json
Экспортирует все данные всех приложений в формате JSON. Флаг --indent=4 делает файл читаемым. Можно ограничить конкретным приложением: dumpdata store.
Восстановление из дампа
python manage.py migrate
python manage.py loaddata db_backup.json
Сначала создаются все таблицы через миграции, затем данные загружаются из дампа.
python manage.py loaddata --exclude auth.permission --exclude contenttypes db_backup.json
⚠️ Проверить по документации: поведение зависит от версии Django и структуры проекта.
5. OpenAPI 3 документация через drf-spectacular
drf-spectacular — современный генератор OpenAPI 3/3.1 схем для Django REST Framework. Он читает ViewSet, Serializer, permissions и authentication settings, а затем отдаёт схему для Swagger UI, ReDoc и клиентской генерации.
Установка
pip install drf-spectacular
Подключение
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'drf_spectacular',
]
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
SPECTACULAR_SETTINGS = {
'TITLE': 'API Documentation',
'DESCRIPTION': 'API documentation for the project',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
}
Маршруты
# urls.py
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularRedocView,
SpectacularSwaggerView,
)
urlpatterns += [
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
path('api/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
]
/api/schema/, UI — /api/docs/, ReDoc — /api/redoc/. Устаревший подход к генерации схем оставлен только в old-vs-new.html как сравнение.