💻 Примеры: паттерны представлений и маршрутов
⚡ Примеры — кратко
# Паттерн 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()),
]