Какую роль выполняет ModelViewSet в Django REST Framework?

Ответ

ModelViewSet в Django REST Framework (DRF) — это высокоуровневый класс, который объединяет в себе логику для полного набора стандартных CRUD-операций (Create, Retrieve, Update, Delete) для одной модели.

Он позволяет значительно сократить количество шаблонного кода, так как наследуется от GenericViewSet и включает в себя следующие mixin-классы:

  • CreateModelMixin — для создания объектов (POST)
  • RetrieveModelMixin — для получения одного объекта (GET by id)
  • UpdateModelMixin — для полного или частичного обновления (PUT/PATCH)
  • DestroyModelMixin — для удаления объекта (DELETE)
  • ListModelMixin — для получения списка объектов (GET list)

Пример использования:

# views.py
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ModelViewSet):
    """Этот ViewSet автоматически предоставляет действия .list(), .retrieve(),
       .create(), .update(), .partial_update() и .destroy()."""
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Основное преимущество ModelViewSet проявляется при использовании с маршрутизаторами (Routers), которые автоматически генерируют URL-шаблоны для всех стандартных действий.

# urls.py
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book')

urlpatterns = router.urls
# Сгенерирует URL-ы типа /books/ и /books/{id}/

Для добавления нестандартных эндпоинтов, не входящих в CRUD, используются декораторы @action.

Ответ 18+ 🔞

А, ну вот, смотри, опять эти ваши вьюсеты, блядь. Сидишь, пишешь одно и то же, как конь, на каждый чих — отдельный класс. А потом бац, и оказывается, есть же штука, которая всё это за тебя делает, ёпта!

Это ModelViewSet, сука. Представь себе такого универсального солдата, который умеет всё: создать запись, достать одну, достать кучу, обновить и нахуй удалить. И не надо городить пять отдельных вьюх, блядь, это всё в одном флаконе, как шампунь «три в одном», только для апишки.

Он внутри себя, этот хитрожопый класс, уже притащил кучу готовых миксинов. Это типа как если бы ты собрал себе бургер из Макдака, а тут тебе сразу целый Биг-Тейсти готовый подвозят. За тебя уже всё смешали: CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin и ListModelMixin. Короче, весь базовый CRUD, нахуй.

Вот смотри, как это просто, ебать мои старые костыли:

# views.py
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ModelViewSet):
    """Этот ViewSet автоматически предоставляет действия .list(), .retrieve(),
       .create(), .update(), .partial_update() и .destroy()."""
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Всё, сука! Шесть действий из коробки. И даже docstring написали, культурные люди, блядь.

А дальше — магия, ёперный театр! Берёшь этот BookViewSet и пихаешь в роутер. Роутер — это такая умная жопа, которая сама нагенерирует все нужные урлы.

# urls.py
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register(r'books', BookViewSet, basename='book')

urlpatterns = router.urls
# Сгенерирует URL-ы типа /books/ и /books/{id}/

И всё, пиздец! У тебя теперь есть /books/ (список и создание) и /books/1/ (получить, обновить, удалить одну). Ни одной строчки урлов вручную не писал, а оно уже работает. Красота, блядь!

Ну а если тебе мало этого стандартного набора и захотелось какую-нибудь свою, ебанутую логику добавить — типа «пометить книгу как прочитанную» или «отправить автору в жопу» — то для этого есть декоратор @action. Он как раз для таких нестандартных выкрутасов. Но это уже, как говорится, совсем другая история, в рот меня чих-пых.