REST框架引入了一個擴展了常規HttpRequest
的Request
對象,並提供了更靈活的請求解析。Request
對象的核心功能是request.data
屬性,它與request.POST
相似,但對於使用Web API更爲有用。html
request.POST # 只處理表單數據 只適用於'POST'方法 request.data # 處理任意數據 適用於'POST','PUT'和'PATCH'方法
REST框架還引入了一個Response
對象,這是一種獲取未渲染(unrendered)內容的TemplateResponse
類型,並使用內容協商來肯定返回給客戶端的正確內容類型python
return Response(data) # 渲染成客戶端請求的內容類型。
在你的視圖(views)中使用純數字的HTTP 狀態碼並不老是那麼容易被理解。並且若是錯誤代碼出錯,很容易被忽略。REST框架爲status
模塊中的每一個狀態代碼(如HTTP_400_BAD_REQUEST
)提供更明確的標識符。使用它們來代替純數字的HTTP狀態碼是個很好的主意。django
REST框架提供了兩個可用於編寫API視圖的包裝器(wrappers)。json
用於基於函數視圖的@api_view
裝飾器。api
用於基於類視圖的APIView
類。瀏覽器
這些包裝器提供了一些功能,例如確保你在視圖中接收到Request
實例,並將上下文添加到Response
,以即可以執行內容協商。微信
包裝器還提供了諸如在適當時候返回405 Method Not Allowed
響應,並處理在使用格式錯誤的輸入來訪問request.data
時發生的任何ParseError
異常。session
好了,咱們要建立一個用於建立簡單Web API的app。app
python manage.py startapp snippets
咱們須要將新建的snippets
app和rest_framework
app添加到INSTALLED_APPS
。讓咱們編輯tutorial/settings.py
文件:框架
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'quickstart.apps.QuickstartConfig', 'snippets.apps.SnippetsConfig', 'rest_framework', ]
請注意若是你使用的Django版本低於1.9,你須要使用snippets.apps.SnippetsConfig
替換snippets
。
好的,咱們開始使用這些新的組件來寫幾個視圖。
咱們在views.py
中再也不須要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 code 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)
咱們的實例視圖是咱們以前例子的改良版。簡明瞭不少,而且目前的代碼和咱們使用Forms API很類似。咱們也用有意義的狀態碼標識符。 在views.py
模塊中,有一個獨立的snippet視圖。
@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)
這對咱們來講應該很是熟悉,由於它與常規的Django視圖沒有什麼區別。 注意,咱們再也不明確打印咱們的對指定內容類型的請求或響應。request.data
可以處理json
請求,可是它也能處理其餘格式。類似地,雖然咱們能夠在響應對象中帶數據,但容許REST框架渲染響應成正確的內容類型。
爲了利用咱們的響應內容再也不是單一格式的事實,咱們應該爲咱們的API尾部添加格式後綴。用格式後綴給咱們明確參考指定格式的URL,這意味着咱們的API可以處理像http://example.com/api/items/4/.json
同樣的連接。 在視圖函數中添加一個format
參數,像這樣:
def snippet_list(request, format=None):
和
def snippet_detail(request, pk, format=None):
如今能夠很快更新urls.py文件,在已經存在的URL中添加一個格式後綴模式(format_suffix_patterns)
。
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模式,可是它給咱們簡單、清楚的方式渲染除特定的格式。
和教程第一部分同樣,咱們要開始從命令行測試API。雖然咱們能在發送無效的請求時更穩當處理錯誤,可是如今一切都作的夠好了。 咱們能想以前同樣獲取全部的snippets列表。
http http://127.0.0.1:8000/snippets/ HTTP/1.1 200 OK ... [ { "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" } ]
咱們能控制咱們返回的響應格式,或者使用Accept
響應頭。
http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSON http http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTML
或者在URL後添加格式後綴:
http http://127.0.0.1:8000/snippets.json # JSON 後綴 http http://127.0.0.1:8000/snippets.api # 瀏覽用的 API 後綴
一樣地,咱們能夠控制咱們發送的請求格式,用Content-Type
請求頭。
# POST using form data http --form POST http://127.0.0.1:8000/snippets/ code="print 123" { "id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly" } # POST using JSON http --json POST http://127.0.0.1:8000/snippets/ code="print 456" { "id": 4, "title": "", "code": "print 456", "linenos": false, "language": "python", "style": "friendly" }
你也能夠從瀏覽器打開API,經過訪問http://127.0.0.1:8000/snippets/。
由於API是基於客戶端請求來選擇響應內容的類型,因此默認狀況下,在Web瀏覽器訪問資源時,API返回HTML格式的資源。這語序API返回徹底能夠網頁瀏覽的HTML。 有能夠網頁瀏覽API是很好的,這使開發和使用你的API更簡單,這也爲其餘想要查看和使用你的API的開發者大大下降了門檻。 關於可瀏覽API的特性和如何自定義可瀏覽API,請見可瀏覽API話題。
咱們基於視圖用類,而且看看普通的視圖咱們如何減小代碼。
掃碼關注微信公衆號 「小樊Study」獲取更多
直男們,掃我送女朋友喲!