JavaRush /Курсы /Модуль 3: Django /Создание простого ViewSet

Создание простого ViewSet

Модуль 3: Django
20 уровень , 2 лекция
Открыта

Сегодня мы создадим наш первый ViewSet.

ViewSet — это класс в DRF, который можно использовать для обработки разных HTTP-методов, таких как GET, POST, PUT, и DELETE. То есть этот класс объединяет логику работы с ресурсом в одном месте.

Стандартные методы для обработки CRUD-операций:

  • List: возврат списка объектов (аналогично GET /resources).
  • Retrieve: возврат данных одного объекта (аналогично GET /resources/{id}).
  • Create: создание нового объекта (аналогично POST /resources).
  • Update: обновление существующего объекта (аналогично PUT /resources/{id}).
  • Delete: удаление объекта (аналогично DELETE /resources/{id}).

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

Зачем использовать ViewSet?

Представьте, что у вас есть ресурс, скажем, "Книги". Если вы планируете создать API для управления этими книгами, то без ViewSet вам нужно было бы написать отдельные функции для каждого действия:

  • Список книг (GET /books)
  • Получение конкретной книги (GET /books/{id})
  • Добавление книги (POST /books)
  • Обновление книги (PUT /books/{id})
  • Удаление книги (DELETE /books/{id})

ViewSet позволяет объединить эту логику в одном месте. Ну, это как супергерой в мире DRF — делает всё сразу и без лишних заморочек.

Создание ViewSet

Шаг 1: подготовка модели

Прежде чем создать ViewSet, нам нужно иметь модель, с которой мы будем работать. Предположим, что у нас есть модель Book, представляющая книги в нашей библиотеке. Вспомним её:

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    published_date = models.DateField()
    isbn = models.CharField(max_length=13)
    pages = models.PositiveIntegerField()

    def __str__(self):
        return self.title

Шаг 2: создание сериализатора

Сериализатор отвечает за преобразование данных между Python-объектами и JSON. Для нашего примера создадим BookSerializer:

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

Здесь мы используем ModelSerializer для автоматической генерации полей на основе модели Book. Это экономит время и избавляет нас от необходимости явно указывать каждое поле.

Шаг 3: создание ViewSet

Теперь время для главного героя сегодняшнего дня — ViewSet! Вот как это делается:

from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from .models import Book
from .serializers import BookSerializer

class BookViewSet(ViewSet):
    """
    Простой ViewSet для управления книгами
    """
    def list(self, request):
        # Получаем все книги из базы данных
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        # Получаем конкретную книгу по primary key (pk)
        book = Book.objects.get(pk=pk)
        serializer = BookSerializer(book)
        return Response(serializer.data)

    def create(self, request):
        # Создаём новую книгу
        serializer = BookSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=201)  # HTTP 201 Created
        return Response(serializer.errors, status=400)  # HTTP 400 Bad Request

Этот ViewSet включает три метода:

  • list: возвращает список всех книг.
  • retrieve: возвращает конкретную книгу по её id.
  • create: позволяет создать новую книгу.

Согласитесь, всё выглядит довольно лаконично, да?

Подключение маршрутов через Router

Одного только ViewSet недостаточно. Нам нужно связать его с URL-адресами, чтобы запросы могли быть обработаны. Для этого в DRF есть специальный класс — Router. Вот как это делается:

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

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

urlpatterns = [
    path('', include(router.urls)),
]

С помощью register мы регистрируем наш BookViewSet под маршрутом /books/. Теперь DRF автоматически создаст маршруты для работы с этим ресурсом. Пример автоматически созданных маршрутов:

  • GET /books/ — список всех книг.
  • GET /books/{id}/ — данные конкретной книги.
  • POST /books/ — создание новой книги.

Примеры запросов в Postman

  1. Получить список книг:

Запрос:

GET /books/

Ответ:

[
    {
        "id": 1,
        "title": "Гарри Поттер и философский камень",
        "author": "Дж. К. Роулинг",
        "published_date": "1997-06-26",
        "isbn": "9780747532699",
        "pages": 223
    },
    {
        "id": 2,
        "title": "Война и мир",
        "author": "Лев Толстой",
        "published_date": "1869-01-01",
        "isbn": "9781234567890",
        "pages": 1225
    }
]
  1. Создать новую книгу:

Запрос:

POST /books/
Content-Type: application/json

Тело запроса:

{
    "title": "1984",
    "author": "Джордж Оруэлл",
    "published_date": "1949-06-08",
    "isbn": "9780451524935",
    "pages": 328
}

Ответ:

{
    "id": 3,
    "title": "1984",
    "author": "Джордж Оруэлл",
    "published_date": "1949-06-08",
    "isbn": "9780451524935",
    "pages": 328
}

Обратная связь и типичные ошибки

На этом этапе можно столкнуться с несколькими проблемами. Например, вы можете забыть зарегистрировать ViewSet в Router. В таком случае будете получать ошибки "404 Not Found" на все запросы, связанные с ресурсом.

Если же вы получаете ошибку "500 Server Error", скорее всего, в коде есть проблемы с сериализатором или моделью (например, отсутствует требуемое поле isbn в базе данных). Убедитесь, что структура модели соответствует сериализатору, и выполните миграции после внесения изменений в модель.

Практическое применение

Использование ViewSet в реальных проектах позволяет значительно ускорить разработку API. Вместо создания кучи отдельных представлений и маршрутов, вы получаете готовый инструмент для обработки CRUD-операций. Это особенно удобно в больших проектах с десятками (если не сотнями) моделей.

Плюс, на собеседованиях часто обсуждают DRF, и понимание того, как работают ViewSet и Router, определённо произведёт хорошее впечатление.

На сегодня всё! Мы только начали знакомиться с ViewSet, но уже научились создавать базовую структуру для ресурса. В следующих лекциях мы углубимся в тему и узнаем, как использовать ModelViewSet и настраивать маршрутизацию более гибким образом.

1
Задача
Модуль 3: Django, 20 уровень, 2 лекция
Недоступна
Создание простого ViewSet для модели "Product"
Создание простого ViewSet для модели "Product"
1
Задача
Модуль 3: Django, 20 уровень, 2 лекция
Недоступна
Расширение ViewSet для модели "Book"
Расширение ViewSet для модели "Book"
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ