請求和響應

請求對象(Request objects)

REST框架引入了一個擴展了常規HttpRequestRequest對象,並提供了更靈活的請求解析。Request對象的核心功能是request.data屬性,它與request.POST相似,但對於使用Web API更爲有用。html

request.POST  # 只處理表單數據  只適用於'POST'方法
request.data  # 處理任意數據  適用於'POST''PUT''PATCH'方法

響應對象(Response objects)

REST框架還引入了一個Response對象,這是一種獲取未渲染(unrendered)內容的TemplateResponse類型,並使用內容協商來肯定返回給客戶端的正確內容類型python

return Response(data)  # 渲染成客戶端請求的內容類型。

狀態碼(Status codes)

在你的視圖(views)中使用純數字的HTTP 狀態碼並不老是那麼容易被理解。並且若是錯誤代碼出錯,很容易被忽略。REST框架爲status模塊中的每一個狀態代碼(如HTTP_400_BAD_REQUEST)提供更明確的標識符。使用它們來代替純數字的HTTP狀態碼是個很好的主意。django

包裝(wrapping)API視圖

REST框架提供了兩個可用於編寫API視圖的包裝器(wrappers)。json

  1. 用於基於函數視圖的@api_view裝飾器。api

  2. 用於基於類視圖的APIView類。瀏覽器

這些包裝器提供了一些功能,例如確保你在視圖中接收到Request實例,並將上下文添加到Response,以即可以執行內容協商。微信

包裝器還提供了諸如在適當時候返回405 Method Not Allowed響應,並處理在使用格式錯誤的輸入來訪問request.data時發生的任何ParseError異常。session

正式開始

好了,咱們要建立一個用於建立簡單Web API的app。app

python manage.py startapp snippets

 

 咱們須要將新建的snippetsapp和rest_frameworkapp添加到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

建立一個model

組合在一塊兒

好的,咱們開始使用這些新的組件來寫幾個視圖。

咱們在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框架渲染響應成正確的內容類型。

在咱們的連接(URLs)後添加可選格式後綴

爲了利用咱們的響應內容再也不是單一格式的事實,咱們應該爲咱們的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/。

Browsability

由於API是基於客戶端請求來選擇響應內容的類型,因此默認狀況下,在Web瀏覽器訪問資源時,API返回HTML格式的資源。這語序API返回徹底能夠網頁瀏覽的HTML。 有能夠網頁瀏覽API是很好的,這使開發和使用你的API更簡單,這也爲其餘想要查看和使用你的API的開發者大大下降了門檻。 關於可瀏覽API的特性和如何自定義可瀏覽API,請見可瀏覽API話題。

接下來要幹什麼?

咱們基於視圖用類,而且看看普通的視圖咱們如何減小代碼。


掃碼關注微信公衆號  「小樊Study」獲取更多

 

直男們,掃我送女朋友喲!

相關文章
相關標籤/搜索