目的
DjangoRestframeworkでModelViewSetを使ってシンプルに爆速でAPIを実装しようと思ったものの、HTTPメソッドによってはデフォルトの動作だけではなく、他の動作を追加してみたいとおもった。
実施環境
ハードウェア環境
項目 | 情報 |
---|---|
OS | macOS Catalina(10.15.7) |
ハードウェア | MacBook Air (11-inch, Early 2015) |
プロセッサ | 1.6 GHz デュアルコアIntel Core i5 |
メモリ | 4 GB 1600 MHz DDR3 |
グラフィックス | intel HD Graphics 6000 1536 MB |
ソフトウェア環境
項目 | 情報 |
---|---|
homebrew | 3.3.8 |
mysql | Ver 8.0.27 for macos10.15 on x86_64 |
python | 3.8.12 |
anaconda | 4.10.1 |
django | 21.2.4 |
pip | 3.1.2 |
前提
ModelViewSetのシンプルな使い方を理解している人向け。
概要
class MemberViewSet(viewsets.ModelViewSet):
queryset = Members.objects.all()
serializer_class = MemberSerializer
この部分は最低限実装することが求められており、これだけでCRUD(create,read,update,delete)が可能となっている。
しかし例えばデータの作成・登録をするときにフロントエンドから送られてきた情報に加工をしたい場合などはこれだけではもちろんできない。
これを可能にするためには
@action→action decoratorの実装が必要となる。
@actionを使って、
① httpメソッドの指定
② pk(主キー/プライマリーキー)の指定
③ クエリセットもしくはオブジェクトの取得
④ 加工・バリデーションなど(実際に何かカスタマイズする部分)
⑤ レスポンス
をすることでデフォルトのものとは全く異なる動作、レスポンスを行うことができる。
urlにはデフォルトのurlに/関数名/
を追加する
##クエリセットとオブジェクトの違い
####クエリセット
オブジェクトのリスト
(例えばgetメソッドでMember.all()などで取得する全部(もしくは一部)の情報)
<QuerySet [<Member: takeshi yoshimoto>, <Member: Yuto Ichihara>]>
####オブジェクト
一列のレコード
(例えばgetメソッドでpkで取得する一列の情報)
<Post: Sample title>
具体例
class MemberViewSet(viewsets.ModelViewSet):
# Membersのクエリセットを全て取得
queryset = Members.objects.all()
# 取得したクエリセットをシリアライズ、デシリアライズ
serializer_class = MemberSerializer
# getでpk有りの詳細情報を取得する際は下記実行される
@action(methods=['get'], detail=True)
def attach_san_to_name(self, request, pk=None):
# Memberの指定したidのレコードを取得
member = self.get_object()
# memberの名前+さんをrespond
return Response('{member.username}さん'.format(member=member))
このようにviews.pyを実装したのちに、
``デフォルトurl/attach_san_to_name/```でこの関数が実行される。
- methodsには対象のHTTPメソッドを記載
- detailはpkが必要な詳細データの場合はTrue, 一覧などが対象ならFalse
- get_objectは「クエリセットとオブジェクトの違い」で示したようにクエリセットならget_querysetを実装。