Django REST framework 處理請(qǐng)求和響應(yīng)有以下幾個(gè)關(guān)鍵點(diǎn)岳悟。
1. 請(qǐng)求對(duì)象(Request objects)
REST 框架擴(kuò)展了 Django 常規(guī)的 HttpRequest
的 Request
對(duì)象佃迄,并提供了更靈活的請(qǐng)求解析。Request 對(duì)象的核心功能是 request.data
屬性贵少,它與 request.POST
類似呵俏,但對(duì)于使用 Web API 更為有用。
request.POST # 只處理表單數(shù)據(jù) 只適用于'POST'方法
request.data # 處理任意數(shù)據(jù) 適用于'POST'滔灶,'PUT'和'PATCH'方法
2. 響應(yīng)對(duì)象(Response objects)
REST 框架還引入了一個(gè) Response
對(duì)象普碎,這是一種獲取未渲染(unrendered)內(nèi)容的 TemplateResponse
類型,并使用內(nèi)容協(xié)商來(lái)確定返回給客戶端的正確內(nèi)容類型录平。
return Response(data) # 渲染成客戶端請(qǐng)求的內(nèi)容類型麻车。
3. 狀態(tài)碼(Status codes)
在你的視圖(views)中使用純數(shù)字的 HTTP 狀態(tài)碼并不總是那么容易被理解缀皱。而且如果錯(cuò)誤代碼出錯(cuò),很容易被忽略动猬。
REST 框架為 status
模塊中的每個(gè)狀態(tài)代碼(如 HTTP_400_BAD_REQUEST
)提供更明確的標(biāo)識(shí)符啤斗。使用它們來(lái)代替純數(shù)字的 HTTP 狀態(tài)碼是個(gè)很好的主意。
4. 包裝(wrapping)API 視圖
REST 框架提供了兩個(gè)可用于編寫 API 視圖的包裝器(wrappers):
- 用于基于函數(shù)視圖的
@api_view
裝飾器赁咙。
- 用于基于函數(shù)視圖的
- 用于基于類視圖的
APIView
類钮莲。
- 用于基于類視圖的
這些包裝器提供了一些功能,例如確保你在視圖中接收到 Request 實(shí)例彼水,并將上下文添加到 Response崔拥,以便可以執(zhí)行內(nèi)容協(xié)商。
包裝器還提供了諸如在適當(dāng)時(shí)候返回 405 Method Not Allowed
響應(yīng)凤覆,并處理在使用格式錯(cuò)誤的輸入來(lái)訪問(wèn) request.data
時(shí)發(fā)生的任何 ParseError
異常链瓦。
組合在一起
好的,我們開(kāi)始把上面幾點(diǎn)組合叛赚。
現(xiàn)在 views.py
中不再需要 JSONResponse
類了澡绩,所以把它刪除掉。刪除之后俺附,我們就可以開(kāi)始重構(gòu)我們的視圖了肥卡。
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from myApp.models import Book
from myApp.serializers import BookSerializer
@api_view(['GET'])
def book_list(request):
all_books = Book.objects.all()
serializer = BookSerializer(all_books, many=True)
return Response(serializer.data)
@api_view(['POST'])
def add_book(request):
serializer = BookSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我們的實(shí)例視圖比前面的示例有所改進(jìn)。它稍微簡(jiǎn)潔一點(diǎn)事镣,現(xiàn)在的代碼與我們使用 Forms
時(shí)非常相似步鉴。我們還使用了命名狀態(tài)代碼,這使得響應(yīng)意義更加明顯璃哟。
給網(wǎng)址添加可選的格式后綴
使用該功能我們能得到諸如 http://example.com/api/book_list.json 之類的 URL氛琢。
首先在視圖中添加一個(gè) format
關(guān)鍵字參數(shù):
def book_list(request, format=None):
......
現(xiàn)在更新 urls.py
,給現(xiàn)有的 URL 后面添加一組 format_suffix_patterns
:
......
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/book_list/', book_list, name='api_book_list'),
url(r'^api/add_book/', add_book, name='api_add_book'),
url(r'^index/', index),
]
urlpatterns = format_suffix_patterns(urlpatterns)
我們就可以這樣獲取 API 的 json:http://127.0.0.1:8000/api/book_list.json