教程2-請求和響應(yīng)(Requests and Response)-DRF(Django REST framework)中文文檔

返回目錄
上一節(jié): 序列化器
從現(xiàn)在開始我們將要真正涉及到REST framework的核心部分, 讓我們先介紹幾個(gè)基本構(gòu)建塊吭敢。

Request 對象

REST框架引入了一個(gè)Request對象碰凶,該對象擴(kuò)展了常規(guī)的HttpRequest,并提供了更靈活的請求解析鹿驼。Request對象中的一個(gè)核心功能就是request.data屬性欲低,與request.POST十分類似,但是在使用Web API的時(shí)候更加有用畜晰。

    request.POST    # 只能處理數(shù)據(jù)砾莱, 只在POST請求時(shí)起作用。
    request.data    # 處理任意數(shù)據(jù)凄鼻,在POST, PUT, PATCH請求下都起作用

Response 對象

REST framework 也提供了Response對象腊瑟,它是SimpleTemplateResponse的一個(gè)子類聚假,接收未經(jīng)渲染的內(nèi)容,并根據(jù)前端要求的格式轉(zhuǎn)換成正確格式內(nèi)容闰非,返回給客戶端膘格。

return Response(data)  # Renders to content type as requested by the client.

狀態(tài)碼

在視圖中使用數(shù)字狀態(tài)碼讀起來并不是很清晰,并且很容易將狀態(tài)碼用混财松,REST framework 提供了更明確定義的狀態(tài)碼瘪贱,比如status模塊中的HTTP_400_BAD_REQUEST,使用這些狀態(tài)碼而不是使用純數(shù)字的狀態(tài)碼是更好的選擇辆毡。

包裝API 視圖

REST framework提供了兩種包裝視圖API的方法菜秦。
1. @api_view裝飾器可以使用在基于函數(shù)的視圖上。
2. APIView類可以使用在基于類的視圖上胚迫。
他們提供了一些使用的方法喷户,比如確保視圖函數(shù)接收到了Request實(shí)例,并且給Response對象添加上下文访锻,以確保內(nèi)容正確的渲染褪尝。
包裝方法還會在合適的時(shí)候響應(yīng)405 Method Not Allowed,也會在輸入的數(shù)據(jù)不完整的時(shí)候期犬,處理ParseError異常河哑。

組合到一起

OK!現(xiàn)在開始使用這些新組件寫幾個(gè)視圖函數(shù)吧龟虎。
我們在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)

我們的視圖較之前的版本有了一些升級佳吞,更加簡潔,而且如果了解Form的API的話棉安,對現(xiàn)在的代碼會似曾相識底扳。我們使用了命名過的狀態(tài)碼,他們使響應(yīng)看起來更加的清晰贡耽,更加語義化衷模。
下面是訪問單獨(dú)代碼片段的視圖函數(shù),同樣也在views.py中蒲赂。

@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常規(guī)的視圖并沒有太大的區(qū)別。
注意我們不再明確地將我們的請求或響應(yīng)綁定到給定的內(nèi)容類型滥嘴。request.data可以處理傳入的json請求木蹬,但它也可以處理其他的格式。類似地若皱,我們返回帶有數(shù)據(jù)的響應(yīng)對象届囚,但允許REST framework將內(nèi)容渲染成正確的類型有梆。

給URL添加可選的格式化后綴

在API的最后,添加格式化后綴意系,可以讓我們體驗(yàn)到不再將響應(yīng)與唯一的內(nèi)容格式綁定的好處,使用格式化后綴可以讓我們通過url來明確地指定需要返回的類型饺汹,這意味著你可以這樣寫urlhttp://example.com/api/items/4.json蛔添。
首先在視圖中添加format關(guān)鍵字參數(shù)。

def snippet_list(request, format=None):

還有:

def snippet_detail(request, pk, format=None):

現(xiàn)在稍微修改snippets/urls.py兜辞,除了現(xiàn)有的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)

我們不一定需要添加這些額外的urlpatterns毕骡,但它為我們提供了一種簡單验辞,干凈的方式來引用特定的格式。

效果

盡管使用命令行工具來測試我們的API吧荣瑟,一切看起來和之前一樣扫皱,雖然我們發(fā)送無效請求的話足绅,會有以下更好的錯(cuò)誤處理。
我們能獲取到所有的代碼片段韩脑,和之前一樣氢妈。

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字段來控制響應(yīng)中的格式:

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

或者通過添加格式化后綴:

http http://127.0.0.1:8000/snippets.json  # JSON suffix
http http://127.0.0.1:8000/snippets.api   # Browsable API suffix

同樣,我們也可以使用請求頭中的Content-Type字段聲明請求中的數(shù)據(jù)格式段多。

# 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"
}

如果你在http請求之前添加了--debug選項(xiàng)首量, 你就可以在請求頭中看到請求的類型了。
現(xiàn)在在瀏覽器中輸入http://127.0.0.1:8000/snippets/ 來打開API进苍。

瀏覽功能

由于API根據(jù)客戶端請求中指定的格式響應(yīng)內(nèi)容類型加缘,當(dāng)使用瀏覽器請求資源的時(shí)候,API會默認(rèn)將資源渲染成HTML的格式觉啊,得到一個(gè)完整的可瀏覽的HTML表現(xiàn)形式拣宏。
擁有可瀏覽的API時(shí)一個(gè)十分有用的功能,使開發(fā)和使用API變得十分容易柄延,同時(shí)也降低了其他檢查或使用你的API的開發(fā)者的準(zhǔn)入門檻蚀浆。
查看(The Browsable API )獲取可瀏覽API的更多信息,并了解如果自定義搜吧。

下一步市俊?

在教程3中,我們要學(xué)習(xí)基于類的視圖滤奈,并了解generic view怎樣節(jié)約我們的代碼量摆昧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蜒程,隨后出現(xiàn)的幾起案子绅你,更是在濱河造成了極大的恐慌伺帘,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忌锯,死亡現(xiàn)場離奇詭異伪嫁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)偶垮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門张咳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人似舵,你說我怎么就攤上這事脚猾。” “怎么了砚哗?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵龙助,是天一觀的道長。 經(jīng)常有香客問我蛛芥,道長提鸟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任常空,我火速辦了婚禮沽一,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘漓糙。我一直安慰自己铣缠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布昆禽。 她就那樣靜靜地躺著蝗蛙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪醉鳖。 梳的紋絲不亂的頭發(fā)上捡硅,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音盗棵,去河邊找鬼壮韭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛纹因,可吹牛的內(nèi)容都是我干的喷屋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼瞭恰,長吁一口氣:“原來是場噩夢啊……” “哼屯曹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤恶耽,失蹤者是張志新(化名)和其女友劉穎密任,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體偷俭,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浪讳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了社搅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驻债。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖形葬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情暮的,我是刑警寧澤笙以,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站冻辩,受9級特大地震影響猖腕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恨闪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一倘感、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咙咽,春花似錦老玛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至溉苛,卻和暖如春镜廉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背愚战。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工娇唯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寂玲。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓塔插,卻偏偏與公主長得像,于是被迫代替她去往敵國和親敢茁。 傳聞我的和親對象是個(gè)殘疾皇子佑淀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容