1. 程式人生 > >rest_framework之status HTTP狀態碼

rest_framework之status HTTP狀態碼

Django Rest Framework有一個status.py的檔案

通常在我們Django檢視(views)中,HTTP狀態碼使用的是純數字,像400,404,200,304等,並不是那麼很好理解這些數字的含義,而且如果錯誤程式碼出錯,很容易被忽略;但是在rest_framework中,REST框架為status模組中的每個狀態碼提供了更明晰的識別符號。使用它們來代替純數字的HTTP狀態碼是一個很不錯的選擇。
狀態碼的使用通常與rest_framework中的Response一塊,我們先看看Response的語法定義:

class Response(SimpleTemplateResponse):
    """
    An HttpResponse that allows its data to be rendered into
    arbitrary media types.
    """

    def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):
        """
        Alters the init arguments slightly.
        For example, drop 'template_name', and instead use 'data'.

        Setting 'renderer' and 'media_type' will typically be deferred,
        For example being set automatically by the `APIView`.
        """
        super(Response, self).__init__(None, status=status)

        if isinstance(data, Serializer):
            msg = (
                'You passed a Serializer instance as data, but '
                'probably meant to pass serialized `.data` or '
                '`.error`. representation.'
            )
            raise AssertionError(msg)

        self.data = data
        self.template_name = template_name
        self.exception = exception
        self.content_type = content_type

        if headers:
            for name, value in six.iteritems(headers):
                self[name] = value
......

主要使用的引數data,status。其中status對應的就是我們要講的status.py中定義的那些狀態碼。

from rest_framework import status
from rest_framework.response import Response

def example_view(self):
    content = {'please move along': 'nothing to see here'}
    return Response(content, status=status.HTTP_404_NOT_FOUND)

status下面列出了模組中包含的完整HTTP狀態程式碼集。該模組還包括一組輔助函式,用於測試狀態程式碼是否在給定範圍內。

from rest_framework import status
from rest_framework.test import APITestCase

class ExampleTestCase(APITestCase):
    def test_url_root(self):
        url = reverse('index')
        response = self.client.get(url)
        self.assertTrue(status.is_success(response.status_code))

有關更詳細的HTTP狀態碼資訊,還可以參閱

RFC 2616RFC 6585

資訊-1xx

此類狀態程式碼表示臨時響應。預設情況下,REST框架中沒有使用1xx狀態程式碼。

def is_informational(code):
    return 100 <= code <= 199


HTTP_100_CONTINUE = 100      # 繼續
HTTP_101_SWITCHING_PROTOCOLS = 101      # 交換協議

成功-2xx

此類狀態程式碼表示已成功接收,理解和接受客戶端的請求。

def is_success(code):
    return 200 <= code <= 299


HTTP_200_OK = 200     # 請求成功OK
HTTP_201_CREATED = 201      # 請求已完成,並導致建立新資源
HTTP_202_ACCEPTED = 202      # 請求已被接受處理,但處理尚未完成
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203      # 非權威資訊
HTTP_204_NO_CONTENT = 204      # 無內容
HTTP_205_RESET_CONTENT = 205      # 重置內容
HTTP_206_PARTIAL_CONTENT = 206      # 伺服器已完成對資源的部分GET請求。部分內容
HTTP_207_MULTI_STATUS = 207      # 多狀態;由WebDAV(RFC 2518)擴充套件的狀態碼,代表之後的訊息體將是一個XML訊息,並且可能依照之前子請求數量的不同,包含一系列獨立的響應程式碼。

重定向-3xx

此類狀態程式碼指示使用者代理需要採取進一步操作才能完成請求。

def is_redirect(code):
    return 300 <= code <= 399


HTTP_300_MULTIPLE_CHOICES = 300      # 請求的資源具有多種選擇
HTTP_301_MOVED_PERMANENTLY = 301      # 已為所請求的資源分配了一個新的永久URI;永久移動
HTTP_302_FOUND = 302      # 請求的網頁被轉移到一個新的地址,但客戶訪問仍繼續通過原始URL地址,重定向,新的URL會在response中的Location中返回,瀏覽器將會使用新的URL發出新的Request。
HTTP_303_SEE_OTHER = 303      # 可以在不同的URI下找到對請求的響應,並且應該使用該資源上的GET方法檢索。
HTTP_304_NOT_MODIFIED = 304      # 如果客戶端已執行條件GET請求並允許訪問,但文件尚未修改,則伺服器應該響應此狀態程式碼。
HTTP_305_USE_PROXY = 305      # 使用代理。必須通過Location欄位給出的代理訪問所請求的資源。
HTTP_306_RESERVED = 306      # 306狀態程式碼在規範的先前版本中使用,不再使用,並且程式碼被保留。
HTTP_307_TEMPORARY_REDIRECT = 307      # 臨時重定向。請求的資源暫時駐留在不同的URI下。

客戶端錯誤-4xx

4xx類狀態程式碼適用於客戶端似乎有錯誤的情況。除了在響應HEAD請求時,伺服器應該包括一個實體,其中包含錯誤情況的解釋,以及它是暫時的還是永久的。

def is_client_error(code):
    return 400 <= code <= 499

HTTP_400_BAD_REQUEST = 400      # 錯誤請求。由於語法格式錯誤,伺服器無法理解請求。客戶端不應該在沒有修改的情況下重複請求。
HTTP_401_UNAUTHORIZED = 401      # 未經授權。該請求需要使用者身份驗證。
HTTP_402_PAYMENT_REQUIRED = 402      # 此程式碼保留供將來使用。
HTTP_403_FORBIDDEN = 403      # 伺服器理解請求,但拒絕履行請求。
HTTP_404_NOT_FOUND = 404      # 伺服器未找到與Request-URI匹配的任何內容。
HTTP_405_METHOD_NOT_ALLOWED = 405      # 客戶端請求中的方法被禁止
HTTP_406_NOT_ACCEPTABLE = 406      # 伺服器無法根據客戶端請求的內容特性完成請求
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407      # 此程式碼類似於401(未授權),但表示客戶端必須首先使用代理進行身份驗證。
HTTP_408_REQUEST_TIMEOUT = 408      # 請求超時。客戶端在伺服器準備等待的時間內沒有產生請求。
HTTP_409_CONFLICT = 409      # 由於與資源的當前狀態衝突,無法完成請求。
HTTP_410_GONE = 410      # 請求的資源在伺服器上不再可用,並且不知道轉發地址。預計這種情況將被視為永久性的。網站設計人員可通過301程式碼指定資源的新位置
HTTP_411_LENGTH_REQUIRED = 411     # 伺服器無法處理客戶端傳送的不帶Content-Length的請求資訊
HTTP_412_PRECONDITION_FAILED = 412      # 在伺服器上測試時,一個或多個請求標頭欄位中給出的前提條件被評估為false。
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413      # 伺服器拒絕處理請求,因為請求實體大於伺服器能夠處理的請求實體。
HTTP_414_REQUEST_URI_TOO_LONG = 414      # 請求的資源URL長於伺服器允許的長度
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415      # 伺服器無法處理請求附帶的媒體格式
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416      # 客戶端請求的範圍無效
HTTP_417_EXPECTATION_FAILED = 417      # 伺服器不滿足請求Expect頭欄位指定的期望值,如果是代理伺服器,可能是下一級伺服器不能滿足請求長。

HTTP_422_UNPROCESSABLE_ENTITY = 422     # 不可處理的請求實體。請求格式正確,但是由於含有語義錯誤,無法響應。
HTTP_423_LOCKED = 423      # 鎖定;當前資源被鎖定。
HTTP_424_FAILED_DEPENDENCY = 424      # 錯誤接洽關係。由於之前的某個請求發生的錯誤,導致當前請求失敗,例如 PROPPATCH。
HTTP_428_PRECONDITION_REQUIRED = 428      # 要求先決條件;先決條件是客戶端傳送 HTTP 請求時,如果想要請求能成功必須滿足一些預設的條件。
HTTP_429_TOO_MANY_REQUESTS = 429      # 請求過多。
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431      # 請求頭欄位太大   
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451      # 因法律原因而被官方審查。

伺服器錯誤-5xx

以數字“5”開頭的響應狀態程式碼表示伺服器知道它已經錯誤或無法執行請求的情況。除了在響應HEAD請求時,伺服器應該包括一個實體,其中包含錯誤情況的解釋,以及它是暫時的還是永久的。

def is_server_error(code):
    return 500 <= code <= 599

HTTP_500_INTERNAL_SERVER_ERROR = 500      # 伺服器內部錯誤,無法完成請求
HTTP_501_NOT_IMPLEMENTED = 501      # 伺服器不支援請求的功能,無法完成請求
HTTP_502_BAD_GATEWAY = 502      # 伺服器在充當閘道器或代理時,在嘗試完成請求時從其訪問的上游伺服器收到無效響應。
HTTP_503_SERVICE_UNAVAILABLE = 503      # 服務不可用;由於伺服器的臨時過載或維護,伺服器當前無法處理請求。一般為暫時性的。
HTTP_504_GATEWAY_TIMEOUT = 504      # 作為閘道器或代理伺服器,伺服器沒有收到來自URI指定的上游伺服器的及時響應(例如HTTP,FTP,LDAP)或嘗試完成時需要訪問的其他輔助伺服器(例如DNS)請求。
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505      # 伺服器不支援或拒絕支援請求訊息中使用的HTTP協議版本。
HTTP_507_INSUFFICIENT_STORAGE = 507      # 儲存空間不足
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511      # 網路認證請求;如果你頻繁使用筆記本和智慧手機,你可能會注意到大量的公用 WIFI 服務要求你必須接受一些協議或者必須登入後才能使用。

輔助助手

以下輔助函式可用於標識響應程式碼的類別。

is_informational()  # 1xx
is_success()        # 2xx
is_redirect()       # 3xx
is_client_error()   # 4xx
is_server_error()   # 5xx

這樣就大大方便了我們對這些狀態碼的認知,以及出現錯誤時的判斷。