Что такое ViewSet в Django REST Framework и в чем его преимущество

Ответ

ViewSet в Django REST Framework (DRF) — это класс, который объединяет логику для набора связанных представлений (views) в одной сущности. Вместо того чтобы создавать отдельные классы для списка, деталей, создания и обновления объекта (ListView, DetailView), ViewSet позволяет определить все эти операции как методы одного класса.

Основное преимущество — уменьшение дублирования кода (DRY).

ViewSet не обрабатывает HTTP-методы (get, post) напрямую. Вместо этого он предоставляет действия (actions), такие как list, retrieve, create, update, destroy.

Пример с ModelViewSet

ModelViewSet — это самый мощный вид ViewSet, который автоматически реализует полный набор CRUD-операций для модели.

  1. Определение ViewSet:

    # views.py
    from rest_framework import viewsets
    from .models import Book
    from .serializers import BookSerializer
    
    class BookViewSet(viewsets.ModelViewSet):
        """
        API эндпоинт, который позволяет просматривать и редактировать книги.
        """
        queryset = Book.objects.all().order_by('-publication_date')
        serializer_class = BookSerializer
  2. Регистрация с помощью Router:

    DRF Router автоматически создает URL-шаблоны на основе зарегистрированного ViewSet.

    # urls.py
    from django.urls import path, include
    from rest_framework.routers import DefaultRouter
    from .views import BookViewSet
    
    # Создаем роутер и регистрируем наш ViewSet
    router = DefaultRouter()
    router.register(r'books', BookViewSet, basename='book')
    
    # URL-шаблоны теперь генерируются роутером автоматически
    urlpatterns = [
        path('', include(router.urls)),
    ]

Результат

Роутер сгенерирует следующие URL-маршруты:

  • GET /books/list() (список всех книг)
  • POST /books/create() (создание новой книги)
  • GET /books/{pk}/retrieve() (получение одной книги)
  • PUT /books/{pk}/update() (полное обновление книги)
  • PATCH /books/{pk}/partial_update() (частичное обновление книги)
  • DELETE /books/{pk}/destroy() (удаление книги)