🔖

Django REST Frameworkの@action(detail=False)とは?detail=Trueとの違いと使い分け

に公開

はじめに

Django REST Framework(DRF)でViewSetを使っていると、
カスタムエンドポイントを追加したい場面が出てきます。

そのときによく出てくるのが以下の記述です。

@action(detail=False)

最初に見たとき、

detail=Falseとはどういう意味なのか?Trueとどう違うのか?」

と疑問に思いました。

本記事では、DRFの@actionデコレーターとdetailオプションについて、解説します。

@actionとは

@actionは、ViewSetクラス内で任意のメソッドに対してURLルーティングを追加できるデコレーターです。
ルーティングの定義をカスタマイズせずに、GET, POSTなどのHTTPメソッドを割り当てることができます。

detail=Truedetail=Falseの違い

オプション 対象 ルーティング 使いどころ
detail=True 単一のオブジェクト /items/{id}/foo/ 個別のデータに対する処理(例:ステータス変更)
detail=False 一覧・全体 /items/foo/ 一覧に対する処理(例:集計、フィルター、バルク処理)

実例

detail=True の場合

@action(detail=True, methods=['post'])
def deactivate(self, request, pk=None):
    item = self.get_object()
    item.is_active = False
    item.save()
    return Response({'status': 'deactivated'})

/items/1/deactivate/ のように、特定のIDに対して処理を行います。

detail=False の場合

@action(detail=False, methods=['get'])
def total(self, request):
    total = Item.objects.count()
    return Response({'total': total})

/items/total/ のように、全体に関する処理(一覧向け) となります。

どんなときに使う?

  • detail=False → 一覧表示中の追加情報を表示したいとき
    (例:件数、平均値など)
  • detail=True → 個別オブジェクトに対してアクションを追加したいとき
    (例:アーカイブ、公開、承認など)

💥 よくある間違いパターン

detail=False にすべきところを detail=True にした場合

例えば、一覧に対する処理(例:全件の集計)にもかかわらず detail=True を指定してしまうと、
URLは /items/{id}/xxx/ のような ID付きのものしか作られなくなります。

@action(detail=True, methods=['get'])  # 本当は False にすべき
def total(self, request, pk=None):
    ...

この場合、/items/total/ にアクセスすると 404エラーになります。
「なぜかURLが存在しない」ように見えるので、意外とつまずきやすいポイントです。

detail=True にすべきところを detail=False にした場合

今度は逆に、個別のオブジェクトに対する処理にもかかわらず detail=False にすると、
IDなしのURLしか作られず、対象のオブジェクトを取得できなくなります。

@action(detail=False, methods=['post'])  # 本当は True にすべき
def deactivate(self, request, pk=None):
    item = self.get_object()  # ← ここでエラー
    ...

このような処理は /items/1/deactivate/ のようなURLが必要ですが、
detail=False だと /items/deactivate/ しか作られず、self.get_object() が動きません。

✅ ポイント

  • detail=True単一オブジェクトに対する処理
  • detail=False一覧・全体に対する処理

迷ったら、「URLにIDが必要な処理かどうか」で判断しましょう

まとめ

パターン エンドポイント例 主な用途 判断ポイント
@action(detail=False) /items/total/ 集計、一覧向けのカスタム処理 IDが不要な処理か?
@action(detail=True) /items/1/deactivate/ 単一オブジェクトへの操作 IDが必要な処理か?

おわりに

DRFのViewSetは便利ですが、カスタムエンドポイントを書くときに
@actiondetailの意味でつまずく人は少なくないと思います。

本記事が参考になれば幸いです。

Discussion