前回は、API Viewのラッパーの一つである「@api_view」デコレータによるAPI Viewの実装方法を学びました。
今回はもう一つのラッパーであるAPIViewクラスについて学びます。
前回
APIView クラスについて
API Viewクラスは、Djangoのクラスベースビューです。
クラスベースビューは、viewを構築する手段の一つで、関数の代わりにPythonオブジェクトとしてビューを定義できます。
公式サイトには、以下のメリットが紹介されています。
・ 特定の HTTP メソッド (
https://docs.djangoproject.com/ja/3.0/topics/class-based-views/intro/GET
、POST
など) に関連するコードの集まりを、条件分岐を使ってかき分けるのではなく、それぞれに独立したメソッドを割り当てることができる。
・ ミックスイン (多重継承) などのオブジェクト指向のテクニックを使って、コードを再利用可能なコンポーネントに分解できる。
API View ~Article 一覧~の作成
最初にArticle一覧を作成しましょう。
API Viewの追加
views.pyに以下のクラスを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# news/api/views.py from rest_framework import status from rest_framework.decorators import api_view from rest_framework.views import APIView # new from rest_framework.response import Response from news.models import Article from news.api.serializers import ArticleSerializer class ArticleListCreateAPIView(APIView): def get(self, request): articles = Article.objects.filter(active=True) 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) |
Django REST FrameworkでAPI Viewを作成するために、「APIView」クラスをインポートしました。
このクラスを新しく作成したArticleListCreateAPIViewクラスに継承させることで、クラスベースビューを作成できます。
また、クラスベースビューでは、GET / POSTメソッドの処理を「def get()」、「def post()」と実装することで、それぞれのリクエストごとに処理することができます。
URLディスパッチャの変更
Article一覧のリクエスト先を以下の通りに修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# news/api/urls.py from django.urls import path from news.api.views import ( ArticleListCreateAPIView, # article_list_create_api_view, article_detail_api_view, ) urlpatterns = [ path("articles/", ArticleListCreateAPIView.as_view(), name="article-list"), # path("articles/", article_list_create_api_view, name="article-list"), path("articles/<int:pk>", article_detail_api_view, name="article-detail"), ] |
クラスベースビューを読み込むとき、「as_view()」と指定する必要があります。
動作確認
「http://localhost:8000/api/articles/」にアクセスして、動作を確認してみましょう。

表示は、OKですね。続いて、記事を投稿できるか確認してみましょう。
Contentに以下のデータを入力し、POSTボタンを押下します。
1 2 3 4 5 6 7 8 |
{ "author": "selfnote", "title": "Class Based View", "body": "This is a post by class based view", "location": "tokyo", "publication_date": "2020-05-25", "active": true } |


新しく「id=5」の記事が追加されました。
記事の投稿も問題ないですね。
API View ~Article 詳細~の作成
次に記事の詳細ページを作成します。
API Viewの追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# news/api/views.py from rest_framework import status from rest_framework.decorators import api_view from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.generics import get_object_or_404 # new from news.models import Article from news.api.serializers import ArticleSerializer class ArticleDetailAPIView(APIView): err_msg = { "error": { "code": 404, "message": "Article not found", }} def get_object(self, pk): article = get_object_or_404(Article, pk=pk) return article def get(self, request, pk): article = self.get_object(pk) serializer = ArticleSerializer(article) return Response(serializer.data) def put(self, request, pk): article = self.get_object(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) def delete(self, request, pk): article = self.get_object(pk) article.delete() return Response(status=status.HTTP_204_NO_CONTENT) |
ArticleDetailAPIViewもArticleListCreateAPIViewと作り方は一緒です。
GET/PUT/DELETEメソッドごとに関数を定義するだけで、それぞれの処理が実装できます。
URLディスパッチャの変更
Article詳細のリクエスト先を記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# news/api/urls.py from django.urls import path from news.api.views import ( ArticleListCreateAPIView, ArticleDetailAPIView # article_list_create_api_view, # article_detail_api_view, ) urlpatterns = [ path("articles/", ArticleListCreateAPIView.as_view(), name="article-list"), path("articles/<int:pk>", ArticleDetailAPIView.as_view(), name="article-detail"), # path("articles/", article_list_create_api_view, name="article-list"), # path("articles/<int:pk>", article_detail_api_view, name="article-detail"), ] |
動作確認
動作確認するために、先ほど作った記事(id=5)の詳細ページにアクセスします。
「http://localhost:8000/api/articles/5」

詳細ページが表示されましたね。
続いて、記事の更新を行いましょう。
Contentに以下のデータを登録して、PUTを押下します。
1 2 3 4 5 6 7 8 |
{ "author": "selfnote", "title": "Update Class Based View", "body": "Update This is a post by class based view", "location": "tokyo", "publication_date": "2020-05-25", "active": true } |


更新も問題ないですね。
最後に画面右上の「DELETEボタン」を押下して、記事を削除してみましょう。

記事の削除もOKですね。
次回
次回は、シリアライズのバリデーションチェックについて学んでいきましょう。
関連記事
こちらもどうぞ
Djangoおすすめ書籍
Djangoを学ぶなら以下の書籍がオススメです。
緑 -> 赤 -> 紫の順でやればOKです。読みやすい英語で書かれているので、英語力もついでに上がるかもしれません^^
コメントを残す
コメントを投稿するにはログインしてください。