Разобравшись с теорией разработки API переходим к практике. Сначала освежим в памяти создание API с нуля с учетом тестирования, организации безопасности и мониторинга, а в будущих модулях разберемся с версионированием.

В занятии используем django-rest-framework, как более популярный API пакет. django-ninja рассмотрим в другом занятии

Львиная доля API в продуктах это или перекладывание JSON из одного формата в другой или выполнение какого-то действия над данными. DRF (django-rest-framework) хорошо справляется с такими задачами, позволяет за минимальное время создать API на основе существующей модели. В этом материале рассмотрим как это происходит, а в следующих "накрутим сверху" тестирование, доступ к данным и мониторинг.

Модели

Хорошо начинать описание API в коде с тестов (согласно Test Driven Development (TDD)), однако, чаще начинается с описания моделей: основных и вспомогательных данных, взаимосвязи между моделями.

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

# models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator, MaxValueValidator

class TimeModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class ContentModel(models.Model):
    is_active = models.BooleanField(default=True)

    slug = models.SlugField(unique=True)
    title = models.CharField(max_length=100, unique=True)
    description = models.TextField(blank=True)

    class Meta:
        abstract = True

    def __str__(self):
        return self.title

class Category(TimeModel, ContentModel):
    """Категория товара"""
    pass

class Tag(TimeModel, ContentModel):
    """Характеристика товара"""
    color = models.CharField(max_length=7, default='#000000')  # HEX color

class Product(TimeModel, ContentModel):
    """Описание товара"""
    PRIORITY_CHOICES = [
        ('low', 'Низкий'),
        ('medium', 'Средний'),
        ('high', 'Высокий'),
    ]

    price = models.DecimalField(max_digits=10, decimal_places=2)
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
    tags = models.ManyToManyField('Tag', blank=True, related_name='products')
    stock_quantity = models.PositiveIntegerField(default=0)

class Review(TimeModel):
    """Отзыв на товар"""
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    rating = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
    content = models.TextField()

    class Meta:
        unique_together = ['product', 'user']  # Один отзыв от пользователя на продукт

Абстрактные модели позволяют систематизировать поведение различных моделей

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

Получить доступ к полному материалу
Полный текст доступен в курсе