Создание Django REST API с Django REST Framework: Полное руководство для начинающих

Введение в Django REST Framework

Что такое REST API и зачем он нужен

REST API (Representational State Transfer Application Programming Interface) – это архитектурный стиль для создания веб-сервисов. Вместо сложного протокола, вроде SOAP, REST использует простые HTTP методы (GET, POST, PUT, DELETE и т.д.) для взаимодействия с ресурсами. Это делает его легким для понимания и использования.

REST API необходимы для:

  • Интеграции между различными системами: Позволяют разным приложениям обмениваться данными.
  • Создания веб- и мобильных приложений: Обеспечивают серверную часть для клиентских приложений.
  • Предоставления доступа к данным: Позволяют сторонним разработчикам получать данные.

Преимущества Django REST Framework

Django REST Framework (DRF) – это мощный и гибкий инструмент для создания RESTful API в Django. Он предоставляет ряд преимуществ:

  • Сериализаторы: Преобразуют сложные объекты Django в JSON и обратно.
  • Представления: Обрабатывают HTTP запросы и возвращают ответы.
  • Аутентификация и авторизация: Предоставляют механизмы для защиты API.
  • Маршрутизация: Упрощают определение URL-адресов для API.
  • Тестирование: Содержат инструменты для тестирования API.
  • Поддержка OpenAPI/Swagger: Автоматическая генерация документации.

Установка Django и Django REST Framework

Сначала установите Django:

pip install django

Затем установите Django REST Framework:

pip install djangorestframework

Создание нового Django проекта

Создайте новый проект Django:

django-admin startproject myproject
cd myproject

Создание нового Django приложения для API

Создайте новое приложение Django для API:

python manage.py startapp myapi

Добавьте 'rest_framework' и 'myapi' в INSTALLED_APPS в settings.py:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'myapi',
]

Определение моделей Django

Создание моделей, представляющих данные API

Предположим, вы хотите создать API для управления рекламными кампаниями. Определите модель Campaign в myapi/models.py:

from django.db import models

class Campaign(models.Model):
    name = models.CharField(max_length=200)
    budget = models.DecimalField(max_digits=10, decimal_places=2)
    start_date = models.DateField()
    end_date = models.DateField()
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return self.name

Миграция базы данных

Создайте и примените миграции:

python manage.py makemigrations myapi
python manage.py migrate

Регистрация моделей в Django Admin (необязательно, но полезно для тестирования)

Зарегистрируйте модель Campaign в myapi/admin.py:

from django.contrib import admin
from .models import Campaign

admin.site.register(Campaign)

Сериализаторы Django REST Framework

Что такое сериализаторы и их роль

Сериализаторы преобразуют объекты Django в JSON (для API ответов) и JSON в объекты Django (для создания и обновления данных).

Создание сериализаторов для моделей

Создайте сериализатор для модели Campaign в myapi/serializers.py:

from rest_framework import serializers
from .models import Campaign

class CampaignSerializer(serializers.ModelSerializer):
    class Meta:
        model = Campaign
        fields = '__all__'

Поля сериализаторов и их настройка

Можно настроить поля сериализатора, например, добавить read_only или write_only:

class CampaignSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=200)
    budget = serializers.DecimalField(max_digits=10, decimal_places=2)
    start_date = serializers.DateField()
    end_date = serializers.DateField()
    is_active = serializers.BooleanField(default=True)

    class Meta:
        model = Campaign
        fields = ['id', 'name', 'budget', 'start_date', 'end_date', 'is_active'] # перечисляем поля
        read_only_fields = ['id'] # указываем поля, доступные только для чтения

Методы validate и create/update сериализаторов

Переопределите методы validate, create и update для добавления логики валидации и обработки данных. Например, валидация бюджета:

class CampaignSerializer(serializers.ModelSerializer):
    class Meta:
        model = Campaign
        fields = '__all__'

    def validate_budget(self, value: float) -> float:
        """Валидация бюджета, убеждаемся, что он больше нуля."""
        if value <= 0:
            raise serializers.ValidationError("Бюджет должен быть больше нуля.")
        return value

    def create(self, validated_data: dict) -> Campaign:
        """Создает новую кампанию."""
        return Campaign.objects.create(**validated_data)

    def update(self, instance: Campaign, validated_data: dict) -> Campaign:
        """Обновляет существующую кампанию."""
        instance.name = validated_data.get('name', instance.name)
        instance.budget = validated_data.get('budget', instance.budget)
        instance.start_date = validated_data.get('start_date', instance.start_date)
        instance.end_date = validated_data.get('end_date', instance.end_date)
        instance.is_active = validated_data.get('is_active', instance.is_active)
        instance.save()
        return instance

Представления Django REST Framework

Обзор различных типов представлений (APIView, GenericAPIView, ViewSets)

  • APIView: Базовый класс для создания представлений.
  • GenericAPIView: Предоставляет общую логику для CRUD операций.
  • ViewSets: Объединяют логику для нескольких связанных представлений.

Использование GenericAPIView и Mixins для CRUD операций

GenericAPIView вместе с mixins (ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin) упрощают создание CRUD операций.

Создание представлений для получения списка объектов (ListAPIView)

from rest_framework import generics
from .models import Campaign
from .serializers import CampaignSerializer

class CampaignList(generics.ListAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

Создание представлений для получения конкретного объекта (RetrieveAPIView)

class CampaignDetail(generics.RetrieveAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

Создание представлений для создания объектов (CreateAPIView)

class CampaignCreate(generics.CreateAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

Создание представлений для обновления объектов (UpdateAPIView)

class CampaignUpdate(generics.UpdateAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

Создание представлений для удаления объектов (DestroyAPIView)

class CampaignDelete(generics.DestroyAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

Использование ViewSets для объединения CRUD операций

ViewSet объединяет все CRUD операции в одном классе:

from rest_framework import viewsets

class CampaignViewSet(viewsets.ModelViewSet):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer

URL-адреса API

Определение URL-адресов для представлений

Определите URL-адреса для представлений в myapi/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('campaigns/', views.CampaignList.as_view()),
    path('campaigns/<int:pk>/', views.CampaignDetail.as_view()),
    path('campaigns/create/', views.CampaignCreate.as_view()),
    path('campaigns/<int:pk>/update/', views.CampaignUpdate.as_view()),
    path('campaigns/<int:pk>/delete/', views.CampaignDelete.as_view()),
]

Включите URL-адреса приложения в urls.py проекта:

from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('myapi.urls')),
]

Использование SimpleRouter и DefaultRouter для автоматической генерации URL

SimpleRouter и DefaultRouter автоматически генерируют URL-адреса для ViewSets:

from rest_framework import routers
from . import views

router = routers.DefaultRouter()
router.register(r'campaigns', views.CampaignViewSet)

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

Настройка URL-адресов вручную

Вы можете настроить URL-адреса вручную, используя path и url.

Тестирование API

Использование Django REST Framework API client (APIView, APIClient)

DRF предоставляет APIClient для тестирования API.

Тестирование эндпоинтов API с помощью Postman или cURL

Postman и cURL – инструменты для отправки HTTP запросов к API.

Написание автоматизированных тестов (unittest, pytest)

Напишите автоматизированные тесты для проверки API. Пример с pytest:

import pytest
from rest_framework.test import APIClient
from myapi.models import Campaign

@pytest.fixture
def api_client():
    return APIClient()

@pytest.mark.django_db
def test_campaign_list(api_client):
    Campaign.objects.create(name='Test Campaign', budget=1000, start_date='2023-01-01', end_date='2023-01-31')
    response = api_client.get('/api/campaigns/')
    assert response.status_code == 200
    assert len(response.data) == 1

Аутентификация и авторизация

Обзор различных схем аутентификации (BasicAuthentication, TokenAuthentication, JWT)

  • BasicAuthentication: Использует имя пользователя и пароль.
  • TokenAuthentication: Использует токены для аутентификации.
  • JWT (JSON Web Token): Использует JWT для аутентификации.

Настройка аутентификации в Django REST Framework

Настройте аутентификацию в settings.py:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
}

Использование разрешений (permissions) для контроля доступа

Используйте разрешения для контроля доступа к API:

from rest_framework import permissions

class CampaignList(generics.ListAPIView):
    queryset = Campaign.objects.all()
    serializer_class = CampaignSerializer
    permission_classes = [permissions.IsAuthenticated]

Создание пользовательских разрешений

Можно создать собственные разрешения, наследуясь от permissions.BasePermission.

Пагинация

Что такое пагинация и зачем она нужна

Пагинация разбивает большие объемы данных на страницы для удобства просмотра.

Настройка пагинации в Django REST Framework

Настройте пагинацию в settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
}

Различные стили пагинации (PageNumberPagination, LimitOffsetPagination, CursorPagination)

  • PageNumberPagination: Использует номера страниц.
  • LimitOffsetPagination: Использует лимит и смещение.
  • CursorPagination: Использует курсор для навигации.

Версионирование API

Зачем нужно версионирование API

Версионирование позволяет вносить изменения в API, не ломая существующие клиентские приложения.

Различные методы версионирования (URL Path, Query Parameter, Accept Header)

  • URL Path: Включает номер версии в URL (например, /api/v1/campaigns).
  • Query Parameter: Использует параметр запроса (например, /api/campaigns?version=1).
  • Accept Header: Использует заголовок Accept.

Настройка версионирования в Django REST Framework

Настройте версионирование в settings.py:

REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
}

Заключение

Обзор пройденного материала

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

Дальнейшие шаги и ресурсы для изучения Django REST Framework

  • Официальная документация Django REST Framework: https://www.django-rest-framework.org/
  • Туториалы и примеры кода на GitHub.
  • Книги и онлайн-курсы по Django REST Framework.

Добавить комментарий