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

В Django REST Framework, классы ViewSets, ModelViewSets и GenericViewSets что делают

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

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

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

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

ViewSets, ModelViewSets и GenericViewSets в Django REST Framework

Это ключевые компоненты DRF, которые упрощают разработку REST API. Они предоставляют различные уровни абстракции и автоматизации.

GenericViewSets

Это базовый класс, который комбинирует функциональность ViewSet с миксинами. Он не содержит никакой реализации actions (методов), но предоставляет механизм для их создания.

from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response

class ArticleViewSet(GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    
    def list(self, request):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
    
    def retrieve(self, request, pk=None):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

GenericViewSet можешь расширить с помощью миксинов:

from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.viewsets import GenericViewSet

class ArticleViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    # list() и retrieve() методы уже есть из миксинов!

ViewSet

Это базовый класс ViewSet, который не предоставляет никаких готовых методов. Используется когда тебе нужна полная гибкость:

from rest_framework.viewsets import ViewSet
from rest_framework.response import Response

class UserViewSet(ViewSet):
    def list(self, request):
        users = User.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)
    
    def retrieve(self, request, pk=None):
        user = User.objects.get(pk=pk)
        serializer = UserSerializer(user)
        return Response(serializer.data)
    
    def create(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)
        return Response(serializer.errors, status=400)

В urls.py:

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

router = DefaultRouter()
router.register(r"users", UserViewSet, basename="user")

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

ModelViewSet

Это наиболее полнофункциональный класс, который автоматически предоставляет все CRUD операции (Create, Read, Update, Delete). Он комбинирует все необходимые миксины:

from rest_framework.viewsets import ModelViewSet

class ProductViewSet(ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    # Автоматически получаешь:
    # - list() → GET /products/
    # - create() → POST /products/
    # - retrieve() → GET /products/{id}/
    # - update() → PUT /products/{id}/
    # - partial_update() → PATCH /products/{id}/
    # - destroy() → DELETE /products/{id}/

Сравнительная таблица

Классlistcreateretrieveupdatedestroy
ViewSetРучная реализацияРучнаяРучнаяРучнаяРучная
GenericViewSetС миксинамиС миксинамиС миксинамиС миксинамиС миксинами
ModelViewSet

Пример: Кастомизация ModelViewSet

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

class ArticleViewSet(ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    
    # Кастомное действие
    @action(detail=True, methods=["post"])
    def publish(self, request, pk=None):
        article = self.get_object()
        article.published = True
        article.save()
        return Response({"status": "article published"})
    
    # GET /articles/{id}/publish/ → вызовет этот метод
    
    def get_queryset(self):
        """Фильтровать в зависимости от пользователя"""
        if self.request.user.is_superuser:
            return Article.objects.all()
        return Article.objects.filter(author=self.request.user)

Когда использовать

  • ViewSet: максимальный контроль, сложная бизнес-логика
  • GenericViewSet + миксины: баланс между гибкостью и удобством
  • ModelViewSet: стандартный CRUD для моделей

Я на практике чаще всего использую ModelViewSet для быстрой разработки, а потом при необходимости переопределяю методы для специфической логики.

В Django REST Framework, классы ViewSets, ModelViewSets и GenericViewSets что делают | PrepBro