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

この記事の続きです。

programming-gogogogo.hatenablog.com

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

www.youtube.com

今度は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については以下に説明がありました。

www.django-rest-framework.org

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の画面が表示されるようになりました) f:id:JunpeiNakasone:20210319065422p:plain

さらに、@api_viewでPOSTも指定しているので画面にデータを入力してPOSTボタンをクリックすると新しくデータが追加されます。
f:id:JunpeiNakasone:20210319065816p:plain f:id:JunpeiNakasone:20210319065831p:plain

次に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で個別にデータが取得できます。
f:id:JunpeiNakasone:20210319214955p:plain

また、データを入力してPUTボタンをクリックすると更新処理も問題なく動きました。
f:id:JunpeiNakasone:20210319215214p:plain f:id:JunpeiNakasone:20210319215227p:plain

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

f:id:JunpeiNakasone:20210319215643p:plain

ひとつずつフィールドを指定せずにモデルから全部のフィールドを取得したい場合は以下のようにallで書くことができます。

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        # fields = ['id', 'title', 'author', 'email']
        fields = '__all__'

f:id:JunpeiNakasone:20210319220005p:plain