DRFにおいて、APIViewを継承した場合、GenericAPIViewを継承した場合、またはRetrieveUpdateDestroyAPIViewを継承した場合など、APIの書き方はいろいろありまして、間違いやすいかな~と思っています。(少なくとも私はそうですが)
それで、まとめてみようの気持ちで本記事を書きました。
では!
APIView
例えばModelsにはBook classがあります。
全てのデータをDBから取り出すのAPIを実装します。
(views.pyとurls.pyのみ載せますね。)
- views.py
class BooksView(APIView):
def get(self,request):
response_msg = {'status': 100, 'msg': '成功'}
books=Book.objects.all()
book_ser=BookSerializer(books,many=True)
response_msg['data']=book_ser.data
return Response(response_msg)
- urls.py
path('books/', views.BooksView.as_view()),
これで、一番基本的な書き方が終了です。
GenericAPIView
そもそも、GenericAPIViewを継承する原因はなんでしょう?
そう!コードを重複しているから!
APIViewを継承した場合、getのみはええだけど、post、putなども同じコードを書くので、効率は悪いです。
ですので、GenericAPIViewはAPIViewの進化版と理解してもいいです!
ここまで話したらもうわかると思いますが、GenericAPIViewはAPIViewを継承しています。
コード:
class BooksView(GenericAPIView):
queryset = Book.objects
serializer_class = BookSerializer
def get(self,request):
#単一のデータを取り出す場合は`self.get_object()`を使えば良い。
book_list=self.get_queryset()
book_ser=self.get_serializer(book_list,many=True)
return Response(book_ser.data)
重複した部分はかなり少なくなりましたよね!
今回はソースコードの解説は行わないですが、次回で解説しようかなと思っています!
再進化! GenericAPIView + ListModelMixin
最進化というのは、コードをもっと簡潔で終わらせるのことです。
先にコードを載せます、
コード:
class BookView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset=Book.objects
serializer_class = BookSerializer
def get(self,request):
return self.list(request)
def post(self,request):
return self.create(request)
getやpostをそのままreturnしたらオッケーのことです。もちろん、ListModelMixin,CreateModelMixin以外、後3つがあります、最後でまたまとめておきます。
また、
GenericAPIView + ListModelMixin + CreateModelMixin = ListCreateAPIView
ま、左側を継承しても、右側を継承しても同じの結果のことです。
継承関係まとめ
CreateAPIView,
ListAPIView,
UpdateAPIView,
RetrieveAPIView,
DestroyAPIView,
ListCreateAPIView,
RetrieveUpdateDestroyAPIView,
RetrieveDestroyAPIView,
RetrieveUpdateAPIView
ListModelMixin,
CreateModelMixin,
UpdateModelMixin,
DestroyModelMixin,
RetrieveModelMixin