GenericAPIView
DRF(Django REST framework)におけるGenericAPIViewは、共通の処理を抽象化し、ビューの実装を簡素化するための基底クラスです。主に以下の機能を提供します:
- クエリセットのフィルタリング
- データの分頁処理
- APIビューの共通メソッドの提供
以下はGenericAPIViewの基本的な構造を示したコードです:
from rest_framework import views, pagination, filters
class CustomGenericAPIView(views.APIView):
filter_backends = []
pagination_class = pagination.PageNumberPagination
def filter_queryset(self, queryset):
for backend in self.filter_backends:
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
@property
def paginator(self):
if not hasattr(self, '_paginator'):
self._paginator = self.pagination_class()
return self._paginator
def paginate_queryset(self, queryset):
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self, data):
return self.paginator.get_paginated_response(data)
DRF組み込み分頁クラスの利用
DRFではPageNumberPaginationおよびLimitOffsetPaginationという2つの基本的な分頁クラスを提供しています。
PageNumberPaginationの利用
ページ番号でデータを取得する分頁方式です。
# ...\luffyapi\luffyapi\apps\course\course_pagination.py
from rest_framework import pagination
class CustomPageNumberPagination(pagination.PageNumberPagination):
page_size = 10
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 50
LimitOffsetPaginationの利用
取得するデータの開始位置(offset)と件数(limit)を指定する分頁方式です。
class CustomLimitOffsetPagination(pagination.LimitOffsetPagination):
default_limit = 10
limit_query_param = 'limit'
offset_query_param = 'start'
max_limit = 100
フィルタリングの実装
組み込みフィルタの使用
DRFではSearchFilterとOrderingFilterを標準で提供しており、以下のように使用します:
from rest_framework import viewsets, filters
from . import models, serializers
class CourseViewSet(viewsets.ModelViewSet):
queryset = models.Course.objects.all()
serializer = serializers.CourseSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['title']
ordering_fields = ['price', 'created_at']
django-filterによる高度なフィルタリング
インストール:
pip install django-filter
設定:
INSTALLED_APPS += ['django_filters']
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
FilterSetの定義
from django_filters import FilterSet, NumberFilter
from . import models
class CourseFilterSet(FilterSet):
price_min = NumberFilter(field_name='price', lookup_expr='gte')
price_max = NumberFilter(field_name='price', lookup_expr='lte')
class Meta:
model = models.Course
fields = ['category', 'instructor']
ビューでの使用
from rest_framework import viewsets
from . import models, serializers, filtersets
from django_filters.rest_framework import DjangoFilterBackend
class CourseViewSet(viewsets.ModelViewSet):
queryset = models.Course.objects.all()
serializer_class = serializers.CourseSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = filtersets.CourseFilterSet
カスタムフィルタの実装
class CustomCourseFilter:
def filter_queryset(self, request, queryset, view):
category = request.query_params.get('custom_category')
if category:
queryset = queryset.filter(category_id=category)
return queryset
# ビューでの適用
class CourseViewSet(CustomGenericAPIView):
filter_backends = [CustomCourseFilter]