この記事の続きです。
programming-gogogogo.hatenablog.com
こちらの動画を見ながらPythonのDjango REST framework(DRF)について勉強しています。
今回はDRFのViewsetsについて勉強します。
公式ドキュメントの説明はこちらです。
https://www.django-rest-framework.org/api-guide/viewsets/#viewsets
ドキュメントの説明を自分は以下のように解釈しました。
Django REST framework allows you to combine the logic for a set of related views in a single class, called a ViewSet. In other frameworks you may also find conceptually similar implementations named something like 'Resources' or 'Controllers'.
DRFでは関連するviewをViewSetというひとつにクラスにまとめることができる。
他のフレームワークでいうところのコントローラやリソースと同じ概念。
A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as .get() or .post(), and instead provides actions such as .list() and .create(). View
ViewSetクラスはクラスが基となるViewで、.get()や.post()メソッドハンドラーは提供しない代わりに、.list()や.create()などのアクションがあるとのこと。
Viewsetを実装するためapi_basic/views.pyにArticleViewsetクラスを追加します。
class ArticleViewSet(viewsets.ViewSet): def list(self, request): articles = Article.objects.all() serializer = ArticleSerializer(articles, many=True) return Response(serializer.data) def create(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) def retrieve(self, request, pk=None): queryset = Article.objects.all() article = get_object_or_404(queryset, pk=pk) serializer = ArticleSerializer(article) return Response(serializer.data) def update(self, request, pk=None): article = Article.objects.get(pk=pk) 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)
次にapi_basic/urls.pyを以下のようにします。
from django.urls import path, include from .views import article_list, article_detail, ArticleAPIView, ArticleDetails, GenericAPIView, ArticleViewSet from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register('article', ArticleViewSet, basename='article') urlpatterns = [ path('viewset/', include(router.urls)), path('viewset/<int:pk>/', include(router.urls)), path('article/', ArticleAPIView.as_view()), path('detail/<int:id>/', ArticleDetails.as_view()), path('generic/article/<int:id>/', GenericAPIView.as_view(),) ]
上記の変更を加えた後にサーバーを再起動して、loalhost:8000/viewset/articleにアクセスするとデータが正常に取得できました。
またlocalhost:8000/viewset/にアクセスするとviewset/配下にあるAPIエンドポイント一覧が表示されるようです。
Createメソッドも実装しているので、管理画面のフォームからPOSTリクエストを送ると正常にデータが追加されました。
urlpatternsでviewset/<int:pk>/のエンドポイントも実装しているので、viewset/article/5/でブラウザにアクセスするとIDが5のデータが取得できます。
またID別に取得した画面ではPUTリクエストを送るフォームがあり、更新処理を行うことができます。
Viewsetを使ったCRUDの実装方法が確認できました。