【学習記録】Django REST frameworkチュートリアル9

この記事の続きです。

programming-gogogogo.hatenablog.com

こちらの動画を見ながらPythonDjango REST framework(DRF)について勉強しています。

www.youtube.com

今回はDjangoのAPIViewを使う形にコードを修正します。
前回は関数を基にしたViewだったのでurlpatternsの第二引数に関数を渡していましたが、今回はクラスを渡すようになります。
(公式ドキュメントではfunction based viewとclass based viewと分けられている)

www.django-rest-framework.org

www.django-rest-framework.org

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)
]

上記内容にコードを変更してサーバーを再起動しても問題なくデータが取得できることを確認します。
f:id:JunpeiNakasone:20210320143219p:plain

関数を基にした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のエンドポイントにアクセスして想定通りにデータが取得できることを確認します。
f:id:JunpeiNakasone:20210320145736p:plain

次の記事でGeneric Viewsを実装していきます。

www.django-rest-framework.org