💻 Примеры: Auth, Permissions, Swagger
Рабочие примеры по темам практикума 10 (Django 6.0, DRF 3.17+)
⚡ Ключевые примеры
# Авто-привязка request.user
def perform_create(self, serializer):
serializer.save(customer=self.request.user)
# Кастомное разрешение (owner-only write)
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
# Проверка пользовательского разрешения
class CanViewStatistics(BasePermission):
def has_permission(self, request, view):
return request.user.has_perm('store.can_view_statistics')
Пример 1: Полная цепочка request.user
Создание заказа с авто-привязкой и список заказов только текущего пользователя.
# views.py
from rest_framework import viewsets
from rest_framework.generics import ListAPIView
from rest_framework.permissions import IsAuthenticated
from .models import Order
from .serializers import OrderSerializer
# ViewSet: авто-привязка при создании
class OrderListCreateView(viewsets.ModelViewSet):
queryset = Order.objects.all()
serializer_class = OrderSerializer
permission_classes = [IsAuthenticated]
def perform_create(self, serializer):
# customer берётся из запроса, не из данных
serializer.save(customer=self.request.user)
# Отдельное представление: только заказы текущего пользователя
class UserOrderListView(ListAPIView):
serializer_class = OrderSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
return Order.objects.filter(customer=self.request.user)
# urls.py
from django.urls import path
from .views import UserOrderListView, OrderListCreateView
urlpatterns = [
path('user-orders/', UserOrderListView.as_view(), name='user-orders'),
path('orders/', OrderListCreateView.as_view({'get': 'list', 'post': 'create'}), name='orders'),
]
Пример 2: Кастомное разрешение IsCustomerOrReadOnly
Объектное разрешение: чтение доступно всем, изменение — только владельцу заказа.
# permissions.py
from rest_framework.permissions import BasePermission
class IsCustomerOrReadOnly(BasePermission):
"""
Разрешает редактирование объектов только их владельцам (customer),
остальным — только чтение.
"""
def has_object_permission(self, request, view, obj):
# Безопасные методы доступны всем
if request.method in ['GET', 'HEAD', 'OPTIONS']:
return True
# Только владелец может изменять или удалять
return obj.customer == request.user
# views.py
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from .models import Order
from .serializers import OrderSerializer
from .permissions import IsCustomerOrReadOnly
class OrderDetailUpdateDeleteView(RetrieveUpdateDestroyAPIView):
queryset = Order.objects.all()
serializer_class = OrderSerializer
permission_classes = [IsCustomerOrReadOnly]
Пример 3: Пользовательское разрешение на уровне модели + эндпоинт статистики
# models.py
from django.db import models
class Order(models.Model):
order_date = models.DateTimeField(auto_now_add=True)
customer = models.ForeignKey('Customer', on_delete=models.PROTECT, related_name='orders')
class Meta:
permissions = [
("can_view_statistics", "Can view statistics"),
]
# permissions.py
from rest_framework.permissions import BasePermission
class CanViewStatistics(BasePermission):
"""
Разрешает доступ к статистике только пользователям с разрешением
'store.can_view_statistics'.
"""
def has_permission(self, request, view):
return request.user.has_perm('store.can_view_statistics')
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .permissions import CanViewStatistics
from .models import Order
class OrderStatisticsView(APIView):
permission_classes = [CanViewStatistics]
def get(self, request, *args, **kwargs):
total_orders = Order.objects.count()
data = {'total_orders': total_orders}
return Response(data)
# urls.py
from .views import OrderStatisticsView
urlpatterns += [
path('order-statistics/', OrderStatisticsView.as_view(), name='order-statistics'),
]
Не забыть: После добавления
Затем в Admin: создать группу "Statistic" с разрешением "Can view statistics" и присвоить нужному пользователю.
Meta.permissions обязательно выполнить:python manage.py makemigrationspython manage.py migrateЗатем в Admin: создать группу "Statistic" с разрешением "Can view statistics" и присвоить нужному пользователю.
Пример 4: dumpdata / loaddata
# Создать полный дамп
python manage.py dumpdata --indent=4 > db_backup.json
# Восстановление после удаления БД:
# 1. Применить все миграции (создать структуру таблиц)
python manage.py migrate
# 2. Загрузить данные из дампа
python manage.py loaddata db_backup.json
Пример 5: OpenAPI 3 через 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'),
]
После запуска сервера документация доступна по адресам:
http://127.0.0.1:8000/api/schema/ — OpenAPI 3 JSON/YAML схемаhttp://127.0.0.1:8000/api/docs/ — интерактивный Swagger UIhttp://127.0.0.1:8000/api/redoc/ — более читаемый ReDoc