Введение в 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.