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=True
とdetail=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は便利ですが、カスタムエンドポイントを書くときに
@action
のdetail
の意味でつまずく人は少なくないと思います。
本記事が参考になれば幸いです。
Discussion