Request 和 Response
這一章將開始覆蓋Rest framework的核心。讓我們來介紹一些基礎元件。
Restquest object
Rest framework 引入了一個繼承於django HttpRequest
的物件Request
,並提供更靈活的解析。Request
的核心是request.data
屬性,他類似於request.POST
,但對web api更有用。
request.POST #只處理form data,而且只適用於`POST`方法
request.data #處理所有資料,適用於 `POST`,`PUT`,`PATCH`
Response Object
Rest framework 也引入了Response
物件,它是一個TemplateResponse
型別,並根據客戶端需求正確返回需要的型別。
return Response(data) # 根據客戶端的需求返回不同的型別。
Status codes
在你的views
中使用HTTP狀態碼,總是不太容易閱讀的,而且稍不注意,你會返回一個錯誤的狀態碼。Rest framework為每個狀態碼提供了更為明確的識別符號。例如 status
模組中的 HTTP_400-BAD_REQUEST
。
裝飾API views
REST framework為你提供了兩個裝飾器,你能夠使用它們來寫你的API views。
-
@api_view
裝飾器適用於function based views -
APIView
裝飾器適用於 class-based views
這些方法提供一些功能,例如確保你的view收到的請求型別是Request
,並將上下文新增到Response
當中,這樣就能根據客戶端的需要返回。
裝飾器還提供行為,例如適當的時候返回405 Method Not Allowed
和當訪問request.data或者輸入錯誤時,處理所有的`ParseError`異常。
結合之前的內容
好,來開始使用新的元件來寫我們的views。
我們再也不需要在views.py
中使用JSONResonse
了。我們來開始重構我們的views.
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)
我們所展示的示例view和之前相比,有了相當大的進展。它更小更簡潔,如果我們正在使用Form API,會發現這個程式碼非常的相似。我們也能夠使用 named status codes
。
接下來,我們將在views.py
模組中展示一個snippet的詳情。
@api_view([`GET`,`PUT`,`DELETE`])
def snippet_detail(request,pk)
```
檢索,更新或者刪除一個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.date)
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.HTPP_400_BAD_REQUEST)
elif request.method == "DELETE":
snippe.delete()
return Response(status.status.HTTP_204_NO_CONTENT)
這一切都應該感覺特別熟悉-它和標準的Django views沒多少不同。
注意:我們不再明確指定 request和response的響應型別。request.data
能夠處理所有進來的json
請求,但他也能夠處理其他的格式。同樣,我們在response中返回我們的資料,但是由REST framework 來幫助我們來為不同的請求做出正確的響應內容。
新增url
為我們剛才編寫的兩個view新增url.
def snippet_list(request,format=None)
def snippet_detail(request,pk,format=None)
現在,我們稍微修改一下我們的urls.py
檔案。
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = [
url(r`^snippets/$`,views.snippet_list),
url(r`^snippets/(?P<pk>[0-9]+)$`,views.snippet_detail),
]
urlpatterns = format_suffix_patterns(urlpatterns)
我們不是必須要新增這些額外的url patterns,但是它給我們一個簡單,乾淨的特定格式。