この記事の続きです。
programming-gogogogo.hatenablog.com
こちらの動画を見ながらPythonのDjango REST framework(DRF)について勉強しています。
今回はDjangoのAPIViewを使う形にコードを修正します。
前回は関数を基にしたViewだったのでurlpatternsの第二引数に関数を渡していましたが、今回はクラスを渡すようになります。
(公式ドキュメントではfunction based viewとclass based viewと分けられている)
api_basic/views.pyに以下のようにAPIViewをimportし新しくArticleAPIViewを追加します。
ArticleAPIViewクラスには引数にAPIViewを渡します。
from rest_framework.views import APIView class ArticleAPIView(APIView): def get(self, request): articles = Article.objects.all() serializer = ArticleSerializer(articles, many=True) return Response(serializer.data) def post(self, request): serializer = ArticleSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
api_basic/urls.pyのarticle/を以下のように変更します。
from django.urls import path from .views import article_list, article_detail, ArticleAPIView urlpatterns = [ # path('article/', article_list), path('article/', ArticleAPIView.as_view()), path('detail/<int:pk>/', article_detail) ]
上記内容にコードを変更してサーバーを再起動しても問題なくデータが取得できることを確認します。
関数を基にしたViewよりもAPIViewを使ってクラスを基にしたViewの方がコードが簡潔になっています。
次にArticleDetailsクラスを以下の内容でapi_basic/views.pyに追加します。
class ArticleDetails(APIView): def get_object(self, id): try: return Article.objects.get(id=id) except Article.DoesNotExist: return HttpResponse(status=status.HTTP_404_NOT_FOUND) def get(self, request, id): article = self.get_object(id) serializer = ArticleSerializer(article) return Response(serializer.data) def put(self, request, id): article = self.get_object(id) serializer = ArticleSerializer(article, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, id): article = self.get_object(id) article.delete() return Response(status=status.HTTP_204_NO_CONTENT)
新しく追加したArticleDetailsクラスをurls.pyに渡すようにapi_basic/urls.pyを以下のように修正します。
from django.urls import path from .views import article_list, article_detail, ArticleAPIView, ArticleDetails urlpatterns = [ # path('article/', article_list), path('article/', ArticleAPIView.as_view()), # path('detail/<int:pk>/', article_detail) path('detail/<int:id>/', ArticleDetails.as_view()) ]
ローカルサーバーを再起動してdetailのエンドポイントにアクセスして想定通りにデータが取得できることを確認します。
次の記事でGeneric Viewsを実装していきます。