Django REST Framework と Vue.js を用いた商品一覧ページの構築

APIView による商品一覧実装

依存ライブラリのインストール

pip install coreapi django-guardian

URL 設定の構成

# urls.py
from django.urls import path, include
from rest_framework.documentation import include_docs_urls

urlpatterns = [
    path('docs/', include_docs_urls(title='ECシステム')),
    path('api-auth/', include('rest_framework.urls')),
]

シリアライザの定義

# serializers.py
from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=120)
    view_count = serializers.IntegerField(default=0)
    main_image = serializers.ImageField()

ビューの実装

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import ProductSerializer
from .models import Product

class ProductListAPI(APIView):
    def get(self, request):
        products = Product.objects.all()
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)

モデルシリアライザの活用

# serializers.py
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'

ネストしたシリアライズ

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = '__all__'

class ProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    
    class Meta:
        model = Product
        fields = '__all__'

GenericView による効率化

# views.py
from rest_framework import generics

class ProductListView(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

ページネーションの実装

# pagination.py
from rest_framework.pagination import PageNumberPagination

class CustomPagination(PageNumberPagination):
    page_size = 12
    page_size_param = 'size'
    max_page_size = 100

設定ファイルの更新

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 12
}

ViewSet と Router の統合

# views.py
from rest_framework import viewsets

class ProductViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
    pagination_class = CustomPagination
    queryset = Product.objects.order_by('id')
    serializer_class = ProductSerializer

ルーティング設定

# urls.py
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register('products', ProductViewSet)

urlpatterns += router.urls

フィルタリング機能の拡張

# filters.py
import django_filters

class ProductFilter(django_filters.FilterSet):
    min_price = django_filters.NumberFilter('price', lookup_expr='gte')
    max_price = django_filters.NumberFilter('price', lookup_expr='lte')
    
    class Meta:
        model = Product
        fields = ['min_price', 'max_price']

ビューへのフィルタ統合

# views.py
from rest_framework import filters
from .filters import ProductFilter

class ProductViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
    filter_backends = [
        DjangoFilterBackend, 
        filters.SearchFilter, 
        filters.OrderingFilter
    ]
    filter_class = ProductFilter
    search_fields = ['name', 'description']
    ordering_fields = ['sales_count', 'created_at']

DRF のリクエスト/レスポンス処理

  • request.data: 解析済みリクエストボディ
  • request.query_params: クエリパラメータ
  • Response オブジェクト: コンテンツネゴシエーション対応

タグ: Django DRF vue.js APIView ModelSerializer

5月14日 19:37 投稿