💻 Примеры: Auth, Permissions, Swagger
Рабочие примеры по темам практикума 10 (Django 5.x, DRF 3.15+)
⚡ Ключевые примеры
# Авто-привязка 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: Swagger через drf-yasg
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'drf_yasg',
]
# urls.py
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="API Documentation",
default_version='v1',
description="API documentation for the project",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@local.com"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns += [
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]
После запуска сервера документация доступна по адресам:
http://127.0.0.1:8000/swagger/ — интерактивный Swagger UIhttp://127.0.0.1:8000/redoc/ — более читаемый ReDoc