コレクションレベルのカスタムエンドポイント実装
detail=Falseを指定することで、モデル全件を対象とするエンドポイントを構築できます。アクティブユーザー数の集計処理を例に説明します。
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
class AccountViewSet(ModelViewSet):
queryset = Account.objects.all()
serializer_class = AccountSerializer
@action(detail=False, methods=['get'])
def active_summary(self, request):
active_count = Account.objects.filter(status='active').count()
return Response({'active_accounts': active_count})
個別レコード操作の実装パターン
detail=Trueを設定すると、特定のリソースインスタンスに対する操作を定義可能です。アカウント一時停止機能の実装例を示します。
class AccountViewSet(ModelViewSet):
# ...省略...
@action(detail=True, methods=['patch'])
def suspend(self, request, pk=None):
target = self.get_object()
target.status = 'suspended'
target.save(update_fields=['status'])
return Response({'result': 'suspension completed'})
マルチメソッドエンドポイントの構築
複数のHTTPメソッドを同一エンドポイントで処理する実装方法です。データ検証と登録を統合したエンドポイント例:
class DataViewSet(ModelViewSet):
# ...省略...
@action(detail=False, methods=['get', 'put'])
def process_data(self, request):
if request.method == 'GET':
return Response({'instruction': 'send_data_via_PUT'})
if request.method == 'PUT':
validation_result = validate_data(request.data)
return Response({'validation': validation_result})
カスタムURLパスの設定テクニック
url_pathとurl_nameパラメータでエンドポイントのURIを最適化します。パスワード再設定機能の実装:
class AuthViewSet(ModelViewSet):
# ...省略...
@action(
detail=True,
methods=['post'],
url_path='reset-password',
url_name='password_reset'
)
def password_renewal(self, request, pk=None):
account = self.get_object()
new_hash = generate_password_hash(request.data['new_password'])
account.set_password(new_hash)
return Response({'status': 'password_updated'})
権限制御の組み込み方法
permission_classesパラメータでカスタムアクションにアクセス制御を適用します。管理者専用の分析データ提供例:
from rest_framework.permissions import IsAdminUser
class AnalyticsViewSet(ModelViewSet):
# ...省略...
@action(
detail=False,
methods=['get'],
permission_classes=[IsAdminUser]
)
def system_metrics(self, request):
metrics = collect_system_data()
return Response(metrics)
バイナリデータ対応の応用例
FileResponseを活用したレポートファイルの配信実装。MIMEタイプとヘッダの設定に注目:
class ReportViewSet(ModelViewSet):
queryset = ReportDocument.objects.all()
serializer_class = ReportSerializer
@action(detail=True, methods=['get'])
def export(self, request, pk=None):
report = self.get_object()
stream = report.generate_pdf_stream()
response = HttpResponse(stream, content_type='application/vnd.pdf')
response['Content-Disposition'] = f'attachment; filename="report_{report.id}.pdf"'
return response