В чем разница между ViewSet, GenericViewSet и ModelViewSet в Django REST Framework

Ответ

Все эти классы в Django REST Framework (DRF) предназначены для уменьшения дублирования кода при создании API, но они предлагают разные уровни абстракции и функциональности.

Их иерархия выглядит так: ModelViewSet > GenericViewSet > ViewSet.

  1. ViewSet

    • Что это: Самый базовый класс. Он объединяет логику для набора связанных представлений в один класс, но не предоставляет реализацию действий (таких как list, create, retrieve) по умолчанию. Вы должны реализовать их самостоятельно.
    • Когда использовать: Когда вам нужна полная свобода и нестандартная логика для эндпоинтов, не привязанная к моделям Django.
  2. GenericViewSet

    • Что это: Наследуется от ViewSet и generics.GenericAPIView. Он предоставляет базовую функциональность для работы с моделями (get_object, get_queryset), но, как и ViewSet, не реализует сами действия. Чтобы получить list или create, нужно подмешивать классы-миксины (например, mixins.ListModelMixin).
    • Когда использовать: Когда вам нужна стандартная логика получения объектов из БД, но вы хотите реализовать только часть CRUD-операций (например, только чтение и создание, без обновления).
  3. ModelViewSet

    • Что это: Самый высокоуровневый класс. Наследуется от GenericViewSet и включает в себя все основные миксины для полного набора CRUD-операций: list, create, retrieve, update, partial_update, destroy.
    • Когда использовать: В большинстве случаев для быстрой реализации стандартного CRUD API для модели Django. Это самый простой и быстрый способ.

Пример с ModelViewSet:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

# Этот класс автоматически создаст все эндпоинты для CRUD-операций с моделью Book
class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # Дополнительно можно настроить права доступа, пагинацию и т.д.
    # permission_classes = [IsAuthenticated]

Итог:

  • ViewSet: Максимальный контроль, вся логика пишется вручную.
  • GenericViewSet: Базовая логика для работы с queryset + ручное подключение нужных действий (миксинов).
  • ModelViewSet: Готовое решение "из коробки" для стандартного CRUD.

Ответ 18+ 🔞

О, слушай, сейчас я тебе так разложу по полочкам эти вьюсеты из DRF, что ты офигеешь, как всё просто, на самом деле. Представь, что ты строишь дом.

ViewSet — это, блядь, голый фундамент и куча кирпичей. Дом? Какой дом? Ты сам, сука, должен всё придумать, где стены, где крыша, где окна. Он просто говорит: «Вот тебе место под дом и идея, что он должен быть». А реализацию действий — list, create, retrieve — ты пишешь сам, с нуля. Полная свобода, но и работы, блядь, овердохуища. Используешь, когда твоя логика — это такой дикий загул, что стандартные шаблоны просто сдохли.

GenericViewSet — это уже фундамент, стены и крыша, но без дверей и окон. Наследуется от ViewSet, но притаскивает с собой GenericAPIView. Уже есть базовые штуки: get_object, get_queryset — то есть он умеет ходить в базу и таскать оттуда модели. Но! Самих действий — нихуя! Хочешь list? Подмешивай миксин ListModelMixin. Хочешь create? Вешай CreateModelMixin. Как конструктор, блядь. Используешь, когда тебе из всего CRUD'а нужны только два действия, а остальные — нахуй не сдались.

ModelViewSet — это, ёпта, готовый таунхаус «под ключ». Заехал и живи. Наследуется от GenericViewSet и включает в себя ВСЕ основные миксины: list, create, retrieve, update, partial_update, destroy. Весь этот цирк с конями. Ты просто говоришь, с какой моделью работаешь и какой сериализатор, а он уже, сука, сам всё делает. В 90% случаев — это твой выбор. Быстро, просто, не надо изобретать велосипед.

Вот тебе живой пример с ModelViewSet, чтоб вообще всё стало ясно:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

# Смотри, какой красавец. Три строчки — и у тебя готовый CRUD API для книг.
# list, create, получить одну, обновить, частично обновить, удалить — всё есть, блядь.
class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()  # Откуда данные таскать
    serializer_class = BookSerializer  # Как их преобразовывать
    # А тут уже по желанию: права, пагинацию, фильтры — навешивай, не стесняйся.
    # permission_classes = [IsAuthenticated]

Итог, коротко и на пальцах:

  • ViewSet: Полный контроль, вся логика — твои мозги и твой код. Для нестандартных хуёв и выкрутасов.
  • GenericViewSet: База для работы с моделью + сам собираешь нужные действия из миксинов. Для кастомных CRUD'ов, где половина операций не нужна.
  • ModelViewSet: Всё готовое, бери и пользуйся. Для стандартного CRUD API по модели — идеально, в рот меня чих-пых.