← Назад к вопросам

Какие есть составляющие компоненты у Django REST framework?

1.8 Middle🔥 231 комментариев
#Django#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные компоненты Django REST Framework

Django REST Framework (DRF) — это один из самых популярных фреймворков для создания REST API на Python. Давайте разберёмся с его архитектурой и основными компонентами.

Архитектурные слои DRF

DRF строится на нескольких ключевых компонентах, которые работают вместе:

┌─────────────────────────────────────────────────────────┐
│ Views (APIView, ViewSets)                               │
│ Обработка HTTP запросов, вызов сериализаторов           │
├─────────────────────────────────────────────────────────┤
│ Serializers (ModelSerializer, Serializer)               │
│ Валидация, преобразование данных в/из JSON              │
├─────────────────────────────────────────────────────────┤
│ Permissions, Authentication, Throttling                 │
│ Контроль доступа и безопасности                         │
├─────────────────────────────────────────────────────────┤
│ Models (Django ORM)                                      │
│ Слой данных и бизнес логика                             │
└─────────────────────────────────────────────────────────┘

1. Views и ViewSets

APIView — базовый класс для создания API endpoints:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class UserListView(APIView):
    """Низкоуровневый контроль над endpoints"""
    
    def get(self, request):
        """GET /users/"""
        users = User.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        """POST /users/"""
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

ViewSets — высокоуровневая абстракция (как контроллер):

from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response

class UserViewSet(ModelViewSet):
    """Автоматически создаёт CRUD операции"""
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        """Фильтрация по пользователю"""
        return User.objects.filter(owner=self.request.user)
    
    @action(detail=True, methods=['post'])
    def activate(self, request, pk=None):
        """POST /users/{id}/activate/ — кастомный action"""
        user = self.get_object()
        user.is_active = True
        user.save()
        return Response({'status': 'user activated'})

# Один ViewSet автоматически создаёт:
# GET    /users/          -> list()
# POST   /users/          -> create()
# GET    /users/{id}/     -> retrieve()
# PUT    /users/{id}/     -> update()
# PATCH  /users/{id}/     -> partial_update()
# DELETE /users/{id}/     -> destroy()
# POST   /users/{id}/activate/ -> activate() (кастомный)

Регистрация маршрутов:

from rest_framework.routers import DefaultRouter
from django.urls import path, include

router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'posts', PostViewSet, basename='post')

urlpatterns = [
    path('api/v1/', include(router.urls)),
]

2. Serializers

Serializers — преобразуют объекты Django в JSON и обратно:

from rest_framework import serializers
from .models import User, Post

class UserSerializer(serializers.ModelSerializer):
    """Автоматический serializer из модели"""
    email = serializers.EmailField()  # Валидация email
    
    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name']
        read_only_fields = ['id']  # Только для чтения
        extra_kwargs = {
            'password': {'write_only': True},  # Не выводить в JSON
            'username': {'required': True, 'allow_blank': False}
        }
    
    def validate_email(self, value):
        """Кастомная валидация email"""
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("Email уже зарегистрирован")
        return value
    
    def create(self, validated_data):
        """Переопределить создание объекта"""
        user = User.objects.create_user(**validated_data)
        return user

Вложенные serializers:

class CommentSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)  # Вложенный serializer
    
    class Meta:
        model = Comment
        fields = ['id', 'text', 'author', 'created_at']

class PostSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True, read_only=True)
    author = UserSerializer(read_only=True)
    
    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author', 'comments']

Общий Serializer (без модели):

class ContactSerializer(serializers.Serializer):
    """Для данных, которые не связаны с моделью"""
    email = serializers.EmailField()
    subject = serializers.CharField(max_length=200)
    message = serializers.CharField()
    
    def validate_email(self, value):
        if not value.endswith(('@example.com',)):
            raise serializers.ValidationError("Only example.com emails allowed")
        return value

3. Authentication (Аутентификация)

Token Authentication:

from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated

class ProtectedView(APIView):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        # request.user содержит аутентифицированного пользователя
        return Response({"user": str(request.user)})

# Клиент отправляет запрос с заголовком:
# Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

JWT Authentication:

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework_simplejwt.views import TokenObtainPairView

class JWTProtectedView(APIView):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request):
        return Response({"message": "Hello authenticated user"})

# URL для получения токена
urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view()),
]

# Клиент:
# 1. POST /api/token/ с username и password -> получает access и refresh токены
# 2. Authorization: Bearer <access_token>

4. Permissions (Разрешения)

Встроенные permissions:

from rest_framework.permissions import (
    AllowAny,                # Всем разрешено
    IsAuthenticated,         # Только аутентифицированным
    IsAdminUser,             # Только администраторам
    IsAuthenticatedOrReadOnly,  # Чтение всем, письмо только auth
)

class PublicView(APIView):
    permission_classes = [AllowAny]  # Всем доступ
    
    def get(self, request):
        return Response({"public": True})

class AdminView(APIView):
    permission_classes = [IsAdminUser]  # Только админы
    
    def get(self, request):
        return Response({"admin": True})

Кастомные permissions:

from rest_framework.permissions import BasePermission

class IsOwnerOrReadOnly(BasePermission):
    """Редактировать может только автор"""
    
    def has_object_permission(self, request, view, obj):
        # Чтение разрешено всем
        if request.method in ['GET', 'HEAD', 'OPTIONS']:
            return True
        # Редактирование только если автор
        return obj.owner == request.user

class PostDetailView(APIView):
    permission_classes = [IsOwnerOrReadOnly]
    
    def put(self, request, pk):
        post = Post.objects.get(pk=pk)
        self.check_object_permissions(request, post)  # Проверяет разрешение
        # ...

5. Throttling (Ограничение частоты)

Защита от DDoS и abuse:

from rest_framework.throttling import UserRateThrottle, AnonRateThrottle

class BurstRateThrottle(UserRateThrottle):
    """100 запросов в минуту для аутентифицированных"""
    scope = 'burst'
    THROTTLE_RATES = {
        'burst': '100/minute',
        'sustained': '1000/hour',
    }

class AnonThrottle(AnonRateThrottle):
    """10 запросов в минуту для анонимных"""
    scope = 'anon'
    THROTTLE_RATES = {'anon': '10/minute'}

class LimitedView(APIView):
    throttle_classes = [BurstRateThrottle, AnonThrottle]
    
    def get(self, request):
        return Response({"limited": True})

# Ответ с информацией о лимитах:
# HTTP/1.1 200 OK
# X-RateLimit-Limit: 100
# X-RateLimit-Remaining: 99
# X-RateLimit-Reset: 1234567890

6. Pagination (Постраничная выдача)

Встроенные paginator'ы:

from rest_framework.pagination import (
    PageNumberPagination,
    LimitOffsetPagination,
    CursorPagination
)

class CustomPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = 'page_size'
    max_page_size = 100  # Максимум на странице

class UserListView(ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    pagination_class = CustomPagination

# Запрос:
# GET /users/?page=2&page_size=50

# Ответ:
# {
#     "count": 1000,
#     "next": "http://example.com/users/?page=3",
#     "previous": "http://example.com/users/?page=1",
#     "results": [...]
# }

7. Filtering и Search

Встроенная фильтрация:

from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

class UserListView(ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
    # Фильтрация по точным полям
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['is_active', 'date_joined']
    
    # Поиск по полям
    search_fields = ['username', 'email', 'first_name']
    
    # Сортировка
    ordering_fields = ['date_joined', 'username']
    ordering = ['-date_joined']

# Запросы:
# GET /users/?is_active=true
# GET /users/?search=john
# GET /users/?ordering=-date_joined

8. Error Handling

Кастомные ошибки:

from rest_framework.exceptions import ValidationError, NotFound, PermissionDenied

class PostDetailView(APIView):
    def get(self, request, pk):
        try:
            post = Post.objects.get(pk=pk)
        except Post.DoesNotExist:
            raise NotFound(detail="Post not found")
        
        if not post.is_published:
            raise PermissionDenied(detail="Post is not published")
        
        serializer = PostSerializer(post)
        return Response(serializer.data)

# Ошибка 404:
# HTTP/1.1 404 Not Found
# {"detail": "Post not found"}

Полный пример микросервиса

from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters.rest_framework import DjangoFilterBackend

class PostViewSet(ModelViewSet):
    """Полный CRUD для постов"""
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['author', 'published']
    search_fields = ['title', 'content']
    ordering = ['-created_at']
    pagination_class = CustomPagination
    
    def get_queryset(self):
        """Только свои посты для редактирования"""
        if self.request.method in ['PUT', 'PATCH', 'DELETE']:
            return Post.objects.filter(author=self.request.user)
        return Post.objects.filter(published=True)
    
    def perform_create(self, serializer):
        """Автоматически устанавливает автора"""
        serializer.save(author=self.request.user)

Компоненты DRF — Сводная таблица

КомпонентНазначениеПример
ViewsОбработка HTTPAPIView, ViewSets
SerializersВалидация и преобразованиеModelSerializer
AuthenticationИдентификация пользователяTokenAuth, JWT
PermissionsКонтроль доступаIsAuthenticated
ThrottlingЛимиты на запросыRateThrottle
PaginationПостраничная выдачаPageNumberPagination
FilteringПоиск и фильтрацияDjangoFilterBackend
RenderersФормат ответаJSONRenderer
ExceptionsОбработка ошибокValidationError

Заключение

Django REST Framework предоставляет полный набор инструментов для создания enterprise-grade REST API. Главные компоненты:

  1. Views/ViewSets — логика обработки запросов
  2. Serializers — валидация и преобразование данных
  3. Authentication — идентификация
  4. Permissions — авторизация
  5. Throttling — защита от перегруза
  6. Pagination — разбиение на страницы
  7. Filtering — поиск и фильтрация

Вместе они создают flexible и robust API framework.