💻 Примеры: паттерны представлений и маршрутов

⚡ Примеры — кратко

# Паттерн 1: ViewSet + Router (Category, Supplier, Address)
class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

router = DefaultRouter()
router.register(r'categories', CategoryViewSet)

# Паттерн 2: Generic Views + ручной URL (Product, Customer...)
class ProductListCreateView(ListCreateAPIView):
    queryset = Product.objects.all()
    def get_serializer_class(self):
        return ProductSerializer if self.request.method == 'GET' else ProductCreateUpdateSerializer

urlpatterns = [
    path('products/', ProductListCreateView.as_view()),
    path('products/<int:pk>/', ProductDetailUpdateDeleteView.as_view()),
]

# Паттерн 3: filter_backends
class ProductViewSet(viewsets.ModelViewSet):
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category', 'price']

Пример 1: ModelViewSet + DefaultRouter (простая модель)

Используется для моделей Category, Supplier, Address — там, где один сериализатор подходит для всех операций.

# store/views.py
from rest_framework import viewsets
from .models import Category
from .serializers import CategorySerializer

class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer

# store/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import CategoryViewSet

router = DefaultRouter()
router.register(r'categories', CategoryViewSet)

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

Результат: Все 6 эндпоинтов CRUD генерируются автоматически.

Пример 2: Generic Views с двумя сериализаторами (сложная модель)

Используется для моделей Product, Customer, Order, OrderItem — где GET возвращает вложенные объекты, POST/PUT принимает FK.

# store/views.py
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView
from .models import Product
from .serializers import ProductSerializer, ProductCreateUpdateSerializer

class ProductListCreateView(ListCreateAPIView):
    queryset = Product.objects.all()

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return ProductSerializer          # вложенные Category, Supplier
        return ProductCreateUpdateSerializer  # FK-ключи category_id, supplier_id


class ProductDetailUpdateDeleteView(RetrieveUpdateDestroyAPIView):
    queryset = Product.objects.all()

    def get_serializer_class(self):
        if self.request.method == 'GET':
            return ProductSerializer
        return ProductCreateUpdateSerializer

# store/urls.py
from django.urls import path
from .views import ProductListCreateView, ProductDetailUpdateDeleteView

urlpatterns = [
    path('products/', ProductListCreateView.as_view()),
    path('products/<int:pk>/', ProductDetailUpdateDeleteView.as_view()),
]

Пример 3: DjangoFilterBackend — фильтрация

# settings.py
INSTALLED_APPS = [
    ...
    'django_filters',
]

# store/views.py
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer, ProductCreateUpdateSerializer

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category', 'price']

Тестирование через Postman или curl:

# Получить продукты с category=2
GET http://localhost:8000/api/products/?category=2

# Получить продукты с конкретной ценой
GET http://localhost:8000/api/products/?price=99.99

# Комбинированная фильтрация
GET http://localhost:8000/api/products/?category=2&price=99.99

Пример 4: Комбинирование нескольких Router в urls.py проекта

# config/urls.py
from django.urls import path, include

urlpatterns = [
    path('api/', include('store.urls')),
]

# store/urls.py — объединяем Router и ручные URL
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import (
    CategoryViewSet, SupplierViewSet, AddressViewSet,
    ProductListCreateView, ProductDetailUpdateDeleteView,
    CustomerListCreateView, CustomerDetailUpdateDeleteView,
)

router = DefaultRouter()
router.register(r'categories', CategoryViewSet)
router.register(r'suppliers', SupplierViewSet)
router.register(r'addresses', AddressViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('products/', ProductListCreateView.as_view()),
    path('products/<int:pk>/', ProductDetailUpdateDeleteView.as_view()),
    path('customers/', CustomerListCreateView.as_view()),
    path('customers/<int:pk>/', CustomerDetailUpdateDeleteView.as_view()),
]
← К оглавлению урока    Задания →