JavaRush /Курси /Модуль 3: Django /Робота з GenericViewSet

Робота з GenericViewSet

Модуль 3: Django
Рівень 20 , Лекція 4
Відкрита

GenericViewSet — це гібрид між класичними ViewSet і Generic Views. Він надає потужний, але гнучкий базовий клас для створення ViewSet, комбінуючи можливості generic-based views (наприклад, такі класи як ListAPIView, RetrieveAPIView) з механікою ViewSet. Це дозволяє нам більш точно керувати доступними діями (CRUD-операціями), обираючи лише ті, що нам потрібні.

Якщо ModelViewSet автоматизує стандартні дії (CRUD) "з коробки", то GenericViewSet вимагає, щоб ви явно вказали, які дії ви збираєтесь використовувати. Він не бере на себе всю магію, що робить його більш кастомізованим.

Чому варто використовувати GenericViewSet?

  1. Гнучкість: ви контролюєте, які дії доступні у вашому API.
  2. Уникнення зайвого коду: використовуєте лише ті методи, які потрібні.
  3. Розширюваність: легко додавати додаткові кастомні методи.

Як це працює?

GenericViewSet працює у поєднанні з міксинами (mixins) — це спеціальні класи, які надають реалізацію типових операцій CRUD. Ось основні міксини, які ви можете використовувати з GenericViewSet:

  • mixins.ListModelMixin: для повернення списку об'єктів.
  • mixins.CreateModelMixin: для створення нового об'єкта.
  • mixins.RetrieveModelMixin: для отримання одного об'єкта.
  • mixins.UpdateModelMixin: для оновлення об'єкта.
  • mixins.DestroyModelMixin: для видалення об'єкта.

Ви можете комбінувати ці міксини так, як вам потрібно, і таким чином керувати функціоналом ViewSet.

Приклад використання GenericViewSet

Давайте реалізуємо простий приклад. У нас є модель Book з атрибутами title і author. Ми хочемо налаштувати API для роботи з цією моделлю, але, скажімо, хочемо обмежитися тільки функціоналом читання (List і Retrieve).

1.Визначення моделі Book

Створимо модель книги, якщо ви ще не зробили це в проєкті:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    def __str__(self):
        return self.title

Не забудьте виконати міграції:

python manage.py makemigrations
python manage.py migrate
  1. Створення серіалізатора

  2. Тепер налаштуємо серіалізатор для нашої моделі:

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
  1. Налаштування GenericViewSet

  2. Тепер створимо ViewSet з використанням GenericViewSet і необхідних міксинів:

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

class BookViewSet(mixins.ListModelMixin,
                  mixins.RetrieveModelMixin,
                  viewsets.GenericViewSet):
    """
    Цей ViewSet дозволяє:
    - Отримати список усіх книг (ListModelMixin)
    - Отримати детальну інформацію про одну книгу (RetrieveModelMixin)
    """
    queryset = Book.objects.all()
    serializer_class = BookSerializer

Зверніть увагу, що ми використовуємо два міксини: ListModelMixin і RetrieveModelMixin. Це означає, що наш ViewSet буде підтримувати тільки дві дії: list (GET /books/) і retrieve (GET /books/<id>/).</id>

  1. Налаштування маршрутів

Додамо маршрути для нашого ViewSet з використанням DefaultRouter:

from rest_framework.routers import DefaultRouter
from .views import BookViewSet

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

urlpatterns = router.urls
  1. Тестування API

Запустіть сервер і протестуйте ендпоінти:

  • Отримати список книг: GET /books/
  • Отримати конкретну книгу: GET /books/<id>/

Ви можете використовувати Postman, cURL або вбудований браузер API DRF для тестування.

Кастомізація GenericViewSet

Іноді вам може знадобитися додати додаткову логіку в ваш ViewSet. Наприклад, ви хочете мати кастомний метод для пошуку книг за автором. Для цього ми можемо визначити власну дію всередині ViewSet.

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

class BookViewSet(mixins.ListModelMixin,
                  mixins.RetrieveModelMixin,
                  viewsets.GenericViewSet):

    queryset = Book.objects.all()
    serializer_class = BookSerializer

    @action(detail=False, methods=['get'])
    def by_author(self, request):
        """
        Кастомна дія для пошуку книг за автором.
        Наприклад: /books/by_author/?author=Толстой
        """
        author = request.query_params.get('author', None)
        if author is not None:
            books = self.queryset.filter(author__icontains=author)
            serializer = self.get_serializer(books, many=True)
            return Response(serializer.data)
        return Response({"error": "Параметр author є обов'язковим."}, status=400)

Тепер у вашому API з'явиться новий маршрут:

  • Пошук книг за автором: GET /books/by_author/?author=<ім'я автора>

Деталі кастомної дії:

  • Метод @action дозволяє створити додаткову дію.
  • detail=False вказує, що ця дія працює зі списком (не з окремим об'єктом).
  • Ви можете додавати свої параметри запиту через request.query_params.

Коли використовувати GenericViewSet?

GenericViewSet ідеально підходить для випадків, коли вам потрібно:

  1. Обмежити функціонал дій (наприклад, тільки list і retrieve).
  2. Додати кастомні методи без зайвого коду.
  3. Розділити логіку і зробити API більш читабельним.

Наприклад, якщо у вас складний додаток із багатьма моделями, і не всі з них потребують повної реалізації CRUD, використання GenericViewSet разом із вибраними міксинами дозволить вам уникнути зайвого коду і зробити API більш керованим.

Типові помилки при роботі з GenericViewSet

  1. Відсутність міксинів. GenericViewSet сам по собі не надає методів, таких як list, retrieve, create. Якщо ти забудеш додати міксини, отримаєш помилку 405 (Method Not Allowed).

  2. Неправильні налаштування маршрутів. Використання неправильного basename або пропуск реєстрації ViewSet у роутері може призвести до того, що твій API не буде доступним.

  3. Неявне повернення даних. Якщо ти забув використати Response у кастомних методах, твій API може поводитися дивно.

  4. Необроблені винятки. Додаючи кастомні методи, переконайся, що ти коректно обробляєш помилки (наприклад, відсутній параметр або некоректний формат даних).

Реальне застосування

Робота з GenericViewSet знадобиться в проєктах, де потрібно:

  • Грамотний розподіл відповідальності між методами API.
  • Мінімалізм для "допоміжних" моделей (наприклад, моделі налаштувань або довідники).
  • Гнучкість у додаванні та кастомізації методів.

У реальному житті розширення GenericViewSet може бути корисним не лише для API, але й для створення допоміжних методів у великих проєктах.

3
Опитування
Вступ до ViewSets, рівень 20, лекція 4
Недоступний
Вступ до ViewSets
Вступ до ViewSets
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ