📖 Теория: 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-yasg — библиотека для генерации Swagger/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. Swagger-документация через drf-yasg
drf-yasg (Yet Another Swagger Generator) — библиотека для автоматической генерации Swagger (OpenAPI 2.0) и ReDoc документации по DRF-представлениям.
Установка
pip install drf-yasg
Подключение
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'drf_yasg',
]
Маршруты
# urls.py
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from rest_framework import permissions
schema_view = get_schema_view(
openapi.Info(title="API Documentation", default_version='v1'),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns += [
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0)),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0)),
]
drf-yasg генерирует OpenAPI 2.0 (Swagger). Современная альтернатива — drf-spectacular, поддерживающая OpenAPI 3.0. В данном практикуме используется drf-yasg согласно источнику лекции.