DRF之請求與響應

Lea4ning發表於2024-04-22

【三】請求與響應

【1】請求

【1.1】Request物件

def __init__(self, request, parsers=None, authenticators=None,
             negotiator=None, parser_context=None)

關鍵字引數:
    - request(HttpRequest). 原始請求例項。
    - parsers(list/tuple). 用於解析請求內容的解析器。
    - authenticators(list/tuple). 用於嘗試驗證請求使用者身份的驗證器。
    - negotiator(None). 協商者,用於內容協商。
    - parser_context(None). 解析器上下文,用於解析器的上下文資訊。
【1.1.1】常用屬性
  • .data

    • request.data 返回解析之後的請求體資料。類似於Django中標準的request.POSTrequest.FILES屬性,但提供如下特性:

      • 包含了解析之後的檔案和非檔案資料

      • 包含了對POST、PUT、PATCH請求方式解析後的資料

      • 利用了REST framework的parsers解析器,不僅支援表單型別資料,也支援JSON資料

  • .query_params

    • request.query_params與Django標準的request.GET相同,只是更換了更符合restful規範的名稱,搜尋引數

【1.2】Parser解析器

  • REST framework 提供了Parser解析器,在接收到請求後會自動根據Content-Type指明的請求資料型別(如JSON、表單等)將請求資料進行parse解析,解析為類字典[QueryDict]物件儲存到Request物件中
  • Request物件的資料是自動根據前端傳送資料的格式進行解析之後的結果。
  • 無論前端傳送的哪種格式的資料,我們都可以以統一的方式讀取資料。
【1.2.1】三種解析器模組
模組 描述 請求編碼格式
JSONParser 用於解析 JSON 請求內容。request.data 將被填充為一個資料字典。 application/json
FormParser 用於解析 HTML 表單內容。request.data 將被填充為一個資料 QueryDict。通常與 MultiPartParser 一起使用以完全支援 HTML 表單資料。 application/x-www-form-urlencoded
MultiPartParser 用於解析多部分 HTML 表單內容,支援檔案上傳。request.datarequest.FILES 將分別被填充為一個 QueryDict 和 MultiValueDict。通常與 FormParser 一起使用以完全支援 HTML 表單資料。 multipart/form-data
【1.2.2】預設配置
  • 預設配置中,三種解析器均被配置,所以當我們使用任意一種編碼格式均可以被解析為request.data

image-20240422203118774

【1.2.3】區域性使用
  • 當我們想要指定某個檢視的請求只可以使用某種編碼格式傳輸,就可以指定
# 匯入模組
from rest_framework.parsers import JSONParser, FormParser


class TaskView(APIView):
    # 當我們指定使用的解析器  # 請求將只能正確的解析出json和urlencoded編碼格式的請求
    parser_classes = [JSONParser, FormParser]

    def get(self, request):
        ser = TaskSer(Task.objects.all(), many=True)
        return Response(ser.data)

image-20240422204006015

【1.2.4】全域性使用
# settings.py

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
    ]
}

【2】響應

【2.1】Response物件

def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):

引數:
    - data:要返回的資料。預設為 None。
    - status:響應狀態碼。預設為 None。
    - template_name:模板名稱,已棄用。改用 data 引數。預設為 None。
    - headers:響應頭資訊。預設為 None。
    - exception:是否為異常響應。預設為 False。
    - content_type:響應內容型別。預設為 None。

【2.1.1】常用屬性
  • .data
    • 傳給response物件的序列化後,但尚未render處理的資料
  • .status_code
    • 狀態碼的數字
  • .content
    • 經過render處理後的響應資料

【2.2】Renderer 渲染器

  • REST framework提供了Renderer 渲染器,用來根據請求頭中的Accept(接收資料型別宣告)來自動轉換響應資料到對應格式。
  • 如果前端請求中未進行Accept宣告,則會採用預設方式處理響應資料,我們可以透過配置來修改預設響應格式
【2.2.1】兩種渲染器模組
模組 描述
JSONOpenAPIRenderer 用於將 API 資料渲染為 OpenAPI(前身為 Swagger)規範的 JSON 格式
BrowsableAPIRenderer 用於將 API 資料渲染為可瀏覽的 HTML 頁面。它為 API 提供了一個互動式的介面,使用者可以在瀏覽器中直觀地瀏覽和測試 API
【2.2.2】預設配置
  • 預設配置中,兩種渲染器都被配置了,所以我們可以在瀏覽器和postman中看到不同的介面

  • 【注】當註冊了rest_framework後,前端介面將會被美化

  • 當只設定json渲染器進行渲染時,drf將使用 JSON 渲染器來渲染所有 API 響應,而不會使用任何模板來生成 HTML 頁面。因此,在瀏覽器上就不會顯示頁面,而是直接顯示 JSON 格式的資料。

image-20240422204408418

image-20240422205318321

【2.2.3】區域性使用
  • 當我們想要指定某個檢視的響應只使用JsonRender渲染
from rest_framework.renderers import JSONRenderer


class TaskView(APIView):
    # 只使用JsonRender渲染響應資料
    renderer_classes = [JSONRenderer]

    def get(self, request):
        ser = TaskSer(Task.objects.all(), many=True)
        return Response(ser.data)

image-20240422205555244

【2.2.4】全域性使用
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ]
}

【2.3】響應狀態碼

  • 為了方便設定狀態碼,REST framewrok在rest_framework.status模組中提供了常用狀態碼常量。
【2.3.1】資訊告知 - 1xx
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
【2.3.2】成功 - 2xx
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS
【2.3.3】重定向 - 3xx
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
【2.3.4】客戶端錯誤 - 4xx
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
【2.3.5】伺服器錯誤 - 5xx
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED

相關文章