[django-rest-framework]02.Request and Response,請求和響應!

本人普通一本,正值大三,爲了能有好的就業,痛定思痛戒掉遊戲!鞭策自己至少一週一篇博客

  • 學習目標:學校課內基礎打紮實,課外學會語言框架,同時提升英語閱讀水平
  • 學習路線(自擬):vue -> djangorestframework -> goland
  • 畢業前想:用前後端分離建成自己的小站,做一款網絡遊戲(愛好而已)

關於本篇djangorestframwork

內容皆會上傳到我的github上:https://github.com/BadbadLoli/django-rest-framework-study

本篇參照官網教程:https://www.django-rest-framework.org/tutorial/2-requests-and-responses/

學習爲主,如有紕漏請大神指正


這一章節,我們將真正開始介紹DRF的核心,讓我們先介紹幾個基本的構建塊

Request對象

DRF通過擴展常用的HttpRequest對象,引入了一個新的Request對象,提供了更加靈活的請求解析,Request對象的核心是request.data屬性,request.data類似於request.POST,但對於處理Web API更加得心應手

  • request.POST:只處理表單數據,只適用於POST請求
  • request.data: 處理任意數據,適用於POST, PUTPATCH請求

Response對象

DRF也提供了一個Response對象,它的類型是TemplateResponse,它接受未渲染的內容,並使用內容協商來確定要返回給客戶端的內容

return Response(data)  # 根據客戶端請求呈現內容類型

狀態碼

在視圖函數中使用HTTP數值狀態碼並不利於閱讀,而且很容易會忽略掉錯誤狀態碼,DRF爲每個狀態碼都提供了一個更加明顯的標識符,例如HTTP_400_BAD_REQUEST,使用這些易讀的標識符而不是數字狀態碼是一種好選擇

wrapping API views

drf提供了兩種wrapper來編寫API視圖函數

  1. @api_view:這個裝飾器用來處理基於函數的視圖
  2. APIView:這個類用來處理基於類的視圖

這些wrapper提供了一些功能,比如確保在在視圖函數中接收request實例的時候,向Response對象添加上下文,以便進行內容協商

上述wrapper同時提供了一些行爲,比如在適當的時候返回405 Method Not Allowed的響應,當request.data裏存在非法輸入的時候,wrapper也會對其當成ParseError異常進行處理

來次實踐

我們現在不再需要用到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):
    # 展示所有或創建一個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)
        
@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.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視圖沒有太大的不同,但現在的代碼更加簡潔,我們用了@api_view的裝飾器,還用了更加具體的命名狀態碼,這使得相應的含義更加明顯

注意,我們不再顯示地將請求或相應綁定到一個給定的類型,request.data可以處理傳入的json請求,也可以處理其他格式,類似的,我們返回帶有數據的response對象,還允許drf把我們的響應渲染到正確的類型裏面。

向url添加後綴

我們使用格式後綴可以讓我們的url處理一種給定格式的url,就好比我們的API能夠處理類似...com/api/items/4.json這樣的url

首先向兩個視圖添加一個format的關鍵字參數

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

然後稍微更新一下url.py

from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    path('snippets/', views.snippet_list),
    path('snippets/<int:pk>', views.snippet_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)

關鍵在最後一句,我們不需要添加額外的url模式,drf爲我們提供了一種引用特定格式的,非常簡單幹淨的方法

開始測試

現在可以運行進行測試了,但與上一章不同的是,如果發送無效的請求,我們有更好的錯誤處理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章