DEV Community

kaede
kaede

Posted on • Edited on

Django REST FRAMEWORK Tutorial 9 -- snippet_detail の GET/PUT/DELTE を APIView で作成する

https://www.django-rest-framework.org/tutorial/2-requests-and-responses/#pulling-it-all-together

Django REST framework の snippet_detail を

@csrf_exempt def snippet_detail(request, pk): 
Enter fullscreen mode Exit fullscreen mode

CSRF の検出除外 から

@api_view(['GET', 'PUT', 'DELETE']) def snippet_detail(request, pk): 
Enter fullscreen mode Exit fullscreen mode

API view に書き直す。
これによって DjangoRestFramework の管理画面がブラウザで使える。

from django.http import HttpResponse 
Enter fullscreen mode Exit fullscreen mode

HttpResponse を使っていたのを

from rest_framework.response import Response 
Enter fullscreen mode Exit fullscreen mode

REST framework の Response に変更

 try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return HttpResponse(status=404) 
Enter fullscreen mode Exit fullscreen mode

この、HttpResponse を

 return Response(status=status.HTTP_404_NOT_FOUND) 
Enter fullscreen mode Exit fullscreen mode

Response にして、status.HTTP_404_NOT_FOUND を返すようにする

前回の記事で削除した snippets/2 をブラウザで見ると

Image description

ちゃんと 404 で DRF の管理画面で表示されている。

しかし、api_view を入れずに csrf_exempt のままだと

"GET /snippets/2/ HTTP/1.1" 500 59081

Image description

404 ではなく 500 が返ってきてしまう。

404 は想定されるエラーで、500 はちゃんと想定できていない、システムの作りが甘い時に出るエラーなんだなぁということが理解できた

GET

 if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) 
Enter fullscreen mode Exit fullscreen mode

GET の Jsonレスポンスも レスポンスにすることで

Image description

DRF の管理画面で綺麗に見れる。

PUT, DELETE

 elif request.method == 'PUT': serializer = SnippetSerializer(snippet, 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': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT) 
Enter fullscreen mode Exit fullscreen mode

PUT と DELETE も snippet_list の時のように
DRF の Response と HTTP ステータスを用いて書き直す。
こちらの方が 204 がなんだっけって考えずに済むので可読性が高い。

Image description

PUT と DELETE は、この詳細画面でボタンから行える。


snippet_detail 全体

@api_view(['GET', 'PUT', 'DELETE',]) def snippet_detail(request, pk): """ Retrieve, update or delete a code snippet. """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': serializer = SnippetSerializer(snippet, 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': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT) 
Enter fullscreen mode Exit fullscreen mode

format=None をつける

https://www.django-rest-framework.org/tutorial/2-requests-and-responses/#adding-optional-format-suffixes-to-our-urls

format=None をつけると .json などの format 接尾辞をつけてリクエストをできるらしい

 

def snippet_list(request): def snippet_detail(request, pk): 
Enter fullscreen mode Exit fullscreen mode

snippet_list, snippet_detail, の引数に

def snippet_list(request, format=None): def snippet_detail(request, pk, format=None): 
Enter fullscreen mode Exit fullscreen mode

format=None をつけて

snippets/urls.py に

from rest_framework.urlpatterns import format_suffix_patterns urlpatterns = format_suffix_patterns(urlpatterns) 
Enter fullscreen mode Exit fullscreen mode

urlpatterns を format_suffix_patterns をかける

Image description

Image description

すると、拡張子に応じて DRF の管理画面と json のみを返すものと切り替えられる。


まとめ

from rest_framework.decorators import api_view @api_view(['GET', 'PUT', 'DELETE']) 
Enter fullscreen mode Exit fullscreen mode

rest_framework の api_view で
snippet_detail など各関数(エンドポイント?)で使う HTTP メソッドを記述して

from rest_framework import status from rest_framework.response import Response return Response(serializer.data, status=status.HTTP_201_CREATED) 
Enter fullscreen mode Exit fullscreen mode

rest_framework の status, Response で
このように status.HTTP_201_CREATED, status.HTTP_204_NO_CONTENT, status.HTTP_400_BAD_REQUEST, status.HTTP_404_NOT_FOUND, これらを使うようにする。

Top comments (0)