1. 程式人生 > >django restframwork教程之Request和Response

django restframwork教程之Request和Response

Request 物件 REST framework 引入了一個擴充套件HttpRequest的請求物件,提供了更靈活的請求解析,Request物件的核心功能是request.data屬性,它類似於request.POST,但是對於Web APIs更實用 request.POST # 僅可處理表單資料,僅僅用於post請求.request.data # 處理任意資料, 可供 'POST', 'PUT' and 'PATCH' 請求使用. Response物件 REST framework 也引入了一個response物件,它是一種TemplateResponse型別,它渲染文字內容,並根據內容決定返回給客戶端的資料型別
return Response(data) # 通過客戶端請求返回渲染的內容 Status Code 狀態碼 在你的檢視中使用數字http 狀態碼不利於閱讀,它很容易讓你不會注意到程式碼的錯誤,REST framework為每個狀態碼提供了更加明確的標示,例如HTTP_400_BAD_REQUEST在status模組中,使用這個來代替數字是一個不錯的方法 封裝API檢視 REST framework提供了兩種封裝器,你可以使用他們寫views
  • @api_view 裝飾器用在函式的view中
  • @APIView 裝飾器用在類的view中
這兩個裝飾器提供了一些功能。例如確保在你的view中收到request請求和在response物件中新增context從而能夠根據內容協商渲染 裝飾器還提供了一些行為,如適當的返回405 Method Not Allowed不允許請求的響應,以及當訪問request.data發生格式錯誤時處理任何ParseError異常 開始組裝使用 接上一篇的程式碼,現在我們的view檢視中不再需要JSONResponse 類,所以先刪除它,然後開始重構我們的檢視 from rest_framework import status
from rest_framework.decorators import api_view from rest_framework.response import Response from snippets.models import Snippet from snippets.serializers import SnippetSerializer @api_view(['GET', 'POST']) def snippet_list (request): """ List all snippets, or create a new snippet. """ if request.method == 'GET' : snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many= True ) return Response(serializer.data) elif request.method == 'POST' : serializer = SnippetSerializer(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(['GET', 'PUT', 'DELETE']) def snippet_detail (request, pk): """ Retrieve, update or delete a snippet instance. """ 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) 這裡程式碼和django的普通檢視沒什麼區別,注意,我們不再明確列印我們的對指定內容型別的請求或響應。request.data能夠處理json請求,但是它也能處理其他格式。相似地,雖然我們可以在響應物件中帶資料,但允許REST框架渲染響應成正確的內容型別。 在我們的UIRLs中新增可選的格式字尾 為了突出我們的response不再是單一的格式內容的事實,讓我們在API URL尾部新增格式字尾,用格式字尾給我們明確參考指定格式的URL,類似於http://example.com/api/items/4.json. 增加format關鍵字引數在views中 def snippet_list (request,format=None) def snippet_detail (request, pk,format=None) : 接著更新我們的urls.py檔案,新增一個format_suffix_patterns的引數 from django.conf.urls import url from snippets import views from rest_framework.urlpatterns import format_suffix_patternsurlpatterns = [ url( r'^snippets/$' , views.snippet_list), url( r'^snippets/(?P<pk>[0-9]+)/$' , views.snippet_detail),]urlpatterns = format_suffix_patterns(urlpatterns) 我們不一定需要新增這些額外的url模式,但它給了我們一個簡單,乾淨的方式來引用一個特定的格式。 看看效果 我們要開始從命令列測試API。雖然我們能在傳送無效的請求時更妥當處理錯誤,但是現在一切都做的夠好了。 我們能想之前一樣獲取所有的snippets列表 預設返回json格式 curl -s http://127.0.0.1:8000/snippets/ | jq .[ { "id" : 1, "title" : "" , "code" : "foo = \" bar\ "\n" , "linenos" : false , "language" : "python" , "style" : "friendly" }, { "id" : 2, "title" : "" , "code" : "print \" hello, world\ "\n" , "linenos" : false , "language" : "python" , "style" : "friendly" }, { "id" : 3, "title" : "" , "code" : "print \" hello, world\ "" , "linenos" : false , "language" : "python" , "style" : "friendly" }] 指定格式訪問
  • 在請求頭中指定格式
curl -s http://127.0.0.1:8000/snippets/ -H "Accept:application/json" # Request JSON curl -s http://127.0.0.1:8000/snippets/ -H "Accept:text/html" # Request HTML
  • 在url中指定格式
curl -s http://127.0.0.1:8000/snippets.json # Request JSON curl -s http://127.0.0.1:8000/snippets.api # Request HTML