📖 Теория: 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

Сначала создаются все таблицы через миграции, затем данные загружаются из дампа.

Осторожно с ContentType: При восстановлении на новой БД могут возникнуть конфликты ContentType. Рекомендуется: 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 vs drf-spectacular: drf-yasg генерирует OpenAPI 2.0 (Swagger). Современная альтернатива — drf-spectacular, поддерживающая OpenAPI 3.0. В данном практикуме используется drf-yasg согласно источнику лекции.
← К оглавлению урока    Справочник →