Apiの多様なレスポンスに対応する

apiのレスポンスを返す時に、JSONResponseというクラスを作ることにより、
JSON onlyのレスポンスを返していましたが、
rest frameworkのResponseクラスを使うことで、多様なレスポンスに対応したいと思います。

flowers/views.pyクラスを開いて以下のように修正します。

まず、rest frameworkのResponseクラスをimportして、
不要になるJSONResponseクラスを削除します。


from rest_framework.response import Response
    

次に、JsonResponseでオブジェクトを作っていた、flower_list apiのGET METHODの
return Objectをrest frameworkのResponseに変更します。


@api_view(['GET','POST'])
def flower_list(request):
     if request.method == 'GET':
         flowers = Flower.objects.all()
         flowers_serializer = FlowerSerializer(flowers, many=True)
         return Response(flowers_serializer.data)
    

そして、JSONResponseを使ってjson形式でFlowerSerializerをオブジェクトを生成していた、
POST METHODでは、引数のrequest.dataをそのまま受け取るように修正します。


elif request.method == 'POST':
    flower_serializer = FlowerSerializer(data=request.data)
    if flower_serializer.is_valid():
        flower_serializer.save()
        return Response(flower_serializer.data, \
            status=status.HTTP_201_CREATED)
        return Response(flower_serializer.errors, \
            status=status.HTTP_400_BAD_REQUEST)
    

修正はこんな感じになり、flower_detail apiにも今回の修正を適用した
全体のソースコードは以下になります。


from django.shortcuts import render
from rest_framework import status
from flowers.models import Flower
from flowers.serializers import FlowerSerializer
from rest_framework.decorators import api_view
from rest_framework.response import Response

@api_view(['GET','POST'])
def flower_list(request):
    if request.method == 'GET':
        flowers = Flower.objects.all()
        flowers_serializer = FlowerSerializer(flowers, many=True)
        return Response(flowers_serializer.data)
    elif request.method == 'POST':
        flower_serializer = FlowerSerializer(data=request.data)
        if flower_serializer.is_valid():
            flower_serializer.save()
            return Response(flower_serializer.data, \
                status=status.HTTP_201_CREATED)
        return Response(flower_serializer.errors, \
            status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET','PUT','DELETE'])
def flower_detail(request, pk):
    try:
        flower = Flower.objects.get(pk=pk)
    except Flower.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        flower_serializer = FlowerSerializer(flower)
        return Response(flower_serializer.data)
    elif request.method == 'PUT':
        flower_serializer = FlowerSerializer(flower, data=request.data)
        if flower_serializer.is_valid():
            flower_serializer.save()
            return Response(flower_serializer.data)
        return Response(flower_serializer.errors, \
            status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        flower.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
    

JSON以外のレスポンスが返ってくるようを試してみる


curl -H "Accept: text/html" -iX GET localhost:8000/flowers/
    

レスポンスは長いので、省略しますが、rest frameworkのResponseクラスを使うことにより、
簡単にJSON以外のレスポンスを返すことができます。

こちらを参考に、知識をまとめています。

初版:2018/6/3

このエントリーをはてなブックマークに追加