1.DRFをインストールする
pip install djangorestframework
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20,
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
2. シリアライザー
from rest_framework import serializers
from .models import Product, Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name', 'slug']
class ProductSerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True)
category_id = serializers.PrimaryKeyRelatedField(
queryset=Category.objects.all(),
source='category',
write_only=True,
)
class Meta:
model = Product
fields = ['id', 'name', 'slug', 'description', 'price',
'category', 'category_id', 'created_at']
read_only_fields = ['id', 'created_at']
def validate_price(self, value):
if value <= 0:
raise serializers.ValidationError('Giá phải lớn hơn 0')
return value
ネストされたシリアライザー (書き込み可能)
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = ['product', 'quantity', 'price']
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(many=True)
class Meta:
model = Order
fields = ['id', 'customer', 'items', 'total', 'created_at']
def create(self, validated_data):
items_data = validated_data.pop('items')
order = Order.objects.create(**validated_data)
for item_data in items_data:
OrderItem.objects.create(order=order, **item_data)
return order
3. APIビュー
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class ProductListAPI(APIView):
def get(self, request):
products = Product.objects.filter(is_active=True)
serializer = ProductSerializer(products, many=True)
return Response(serializer.data)
def post(self, request):
serializer = ProductSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
4. GenericAPIView とミックスイン
from rest_framework.generics import (
ListCreateAPIView,
RetrieveUpdateDestroyAPIView,
)
class ProductListCreateAPI(ListCreateAPIView):
queryset = Product.objects.filter(is_active=True)
serializer_class = ProductSerializer
def get_queryset(self):
qs = super().get_queryset()
category = self.request.query_params.get('category')
if category:
qs = qs.filter(category__slug=category)
return qs
class ProductDetailAPI(RetrieveUpdateDestroyAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
lookup_field = 'slug'
5. URLの設定
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('api/products/', views.ProductListCreateAPI.as_view()),
path('api/products/<slug:slug>/', views.ProductDetailAPI.as_view()),
]
次の記事: ビューセット、ルーター、ページネーション — 最適化された API ビュー。