この記事の続きです。
programming-gogogogo.hatenablog.com
こちらの動画を見ながらPythonのDjango REST framework(DRF)について勉強しています。
今度はcsrf_exemptではなく@api_viewを使うコードに変更します。
api_basic/views.pyのarticle_list関数を以下のように修正します。
from django.shortcuts import render from django.http import HttpResponse, JsonResponse from rest_framework.parsers import JSONParser from .models import Article from .serializers import ArticleSerializer from django.views.decorators.csrf import csrf_exempt from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework import status @api_view(['GET', 'POST']) def article_list(request): if request.method == 'GET': articles = Article.objects.all() serializer = ArticleSerializer(articles, many=True) return Response(serializer.data) elif request.method == 'POST': 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_viewについては以下に説明がありました。
The core of this functionality is the api_view decorator, which takes a list of HTTP methods that your view should respond to. viewがレスポンスを返すHTTPメソッドを指定することができるようです。
上記コードでローカルサーバーを再起動しlocalhost:8000/article/にアクセスするとDRFの画面が表示されレスポンスが返されます。
(@csrf_exemptの時はただjsonが画面に表示されるだけでしたが、@api_viewにすると同じリクエスト内容でDRFの画面が表示されるようになりました)
さらに、@api_viewでPOSTも指定しているので画面にデータを入力してPOSTボタンをクリックすると新しくデータが追加されます。
次にarticle_detail関数を@api_viewを使って以下のように修正します。
@api_view(['GET', 'PUT', 'DELETE']) def article_detail(request, pk): try: article = Article.objects.get(pk=pk) except Article.DoesNotExist: return HttpResponse(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = ArticleSerializer(article) return Response(serializer.data) elif request.method == 'PUT': 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) elif request.method == 'DELETE': article.delete() return Response(status=status.HTTP_204_NO_CONTENT)
するとlocalhost:8000/detail/articleのIDで個別にデータが取得できます。
また、データを入力してPUTボタンをクリックすると更新処理も問題なく動きました。
serializer
localhost:8000/articleで一覧取得する際にid、title、authorが取得できるのはserializerでfieldsに以下のようにフィールドを指定しているからで
class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['id', 'title', 'author']
fieldsにemailも加えるとemailのデータも取得できるようになります。
class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['id', 'title', 'author', 'email']
ひとつずつフィールドを指定せずにモデルから全部のフィールドを取得したい場合は以下のようにallで書くことができます。
class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article # fields = ['id', 'title', 'author', 'email'] fields = '__all__'