請求和回應物件

快速概觀

Django 使用請求和回應物件在系統中傳遞狀態。

當請求一個頁面時,Django 會建立一個 HttpRequest 物件,其中包含關於請求的中繼資料。然後 Django 會載入適當的視圖,將 HttpRequest 作為第一個引數傳遞給視圖函式。每個視圖都負責返回一個 HttpResponse 物件。

本文檔說明 HttpRequestHttpResponse 物件的 API,它們定義在 django.http 模組中。

HttpRequest 物件

class HttpRequest[原始碼]

屬性

除非另有說明,否則所有屬性都應視為唯讀。

HttpRequest.scheme[原始碼]

一個字串,表示請求的協定 (通常是 httphttps)。

HttpRequest.body[原始碼]

原始 HTTP 請求主體,為位元組字串。這對於以不同於傳統 HTML 表單的方式處理資料非常有用:二進制圖片、XML 酬載等。對於處理傳統表單資料,請使用 HttpRequest.POST

您也可以使用類似檔案的介面,透過 HttpRequest.read()HttpRequest.readline()HttpRequest 讀取。在使用任一 I/O 流方法讀取請求,存取 body 屬性將會產生 RawPostDataException

HttpRequest.path

一個字串,表示請求頁面的完整路徑,不包括協定、網域或查詢字串。

範例:"/music/bands/the_beatles/"

HttpRequest.path_info

在某些 Web 伺服器配置中,主機名稱後面的 URL 部分會分成腳本前綴部分和路徑資訊部分。path_info 屬性始終包含路徑的路徑資訊部分,無論使用哪個 Web 伺服器。使用此屬性而不是 path 可以讓您的程式碼更容易在測試和部署伺服器之間移動。

例如,如果您的應用程式的 WSGIScriptAlias 設定為 "/minfo",則 path 可能是 "/minfo/music/bands/the_beatles/",而 path_info 將會是 "/music/bands/the_beatles/"

HttpRequest.method

一個字串,表示請求中使用的 HTTP 方法。這保證是大寫。例如

if request.method == "GET":
    do_something()
elif request.method == "POST":
    do_something_else()
HttpRequest.encoding[原始碼]

一個字串,表示目前用於解碼表單提交資料的編碼 (或 None,這表示使用 DEFAULT_CHARSET 設定)。您可以寫入此屬性,以變更存取表單資料時使用的編碼。任何後續屬性存取 (例如從 GETPOST 讀取) 都會使用新的 encoding 值。如果您知道表單資料不是以 DEFAULT_CHARSET 編碼,則此功能非常有用。

HttpRequest.content_type

一個字串,表示請求的 MIME 類型,從 CONTENT_TYPE 標頭剖析。

HttpRequest.content_params

一個字典,包含 CONTENT_TYPE 標頭中包含的鍵/值參數。

HttpRequest.GET

一個類似字典的物件,包含所有給定的 HTTP GET 參數。請參閱下方的 QueryDict 文件。

HttpRequest.POST

一個類似字典的物件,包含所有給定的 HTTP POST 參數,前提是請求包含表單資料。請參閱下方的 QueryDict 文件。如果您需要存取請求中張貼的原始或非表單資料,請改透過 HttpRequest.body 屬性存取。

可能會透過 POST 傳入一個空的 POST 字典的請求 – 例如,如果透過 POST HTTP 方法請求表單,但不包含表單資料。因此,您不應該使用 if request.POST 來檢查 POST 方法的使用;而是使用 if request.method == "POST" (請參閱 HttpRequest.method)。

POST 不包含檔案上傳資訊。請參閱 FILES

HttpRequest.COOKIES

一個字典,包含所有 Cookie。鍵和值都是字串。

HttpRequest.FILES

一個類似字典的物件,包含所有已上傳的檔案。 FILES 中的每個鍵都是來自 <input type="file" name="">nameFILES 中的每個值都是一個 UploadedFile

請參閱 管理檔案 以取得更多資訊。

只有在請求方法為 POST 且發送請求的 <form> 具有 enctype="multipart/form-data" 時,FILES 才會包含資料。 否則,FILES 將會是一個空白的類字典物件。

HttpRequest.META

一個字典,包含所有可用的 HTTP 標頭。可用的標頭取決於客戶端和伺服器,但以下是一些範例:

  • CONTENT_LENGTH – 請求主體的長度(以字串表示)。

  • CONTENT_TYPE – 請求主體的 MIME 類型。

  • HTTP_ACCEPT – 回應可接受的內容類型。

  • HTTP_ACCEPT_ENCODING – 回應可接受的編碼方式。

  • HTTP_ACCEPT_LANGUAGE – 回應可接受的語言。

  • HTTP_HOST – 客戶端發送的 HTTP Host 標頭。

  • HTTP_REFERER – 參考頁面(如果有的話)。

  • HTTP_USER_AGENT – 客戶端的 user-agent 字串。

  • QUERY_STRING – 查詢字串,以單一(未解析)字串表示。

  • REMOTE_ADDR – 客戶端的 IP 位址。

  • REMOTE_HOST – 客戶端的主機名稱。

  • REMOTE_USER – 由 Web 伺服器驗證的使用者(如果有的話)。

  • REQUEST_METHOD – 一個字串,例如 "GET""POST"

  • SERVER_NAME – 伺服器的主機名稱。

  • SERVER_PORT – 伺服器的連接埠(以字串表示)。

除了上述的 CONTENT_LENGTHCONTENT_TYPE 之外,請求中的任何 HTTP 標頭都會轉換為 META 的鍵,方法是將所有字元轉換為大寫,將任何連字符號取代為底線,並在名稱前加上 HTTP_ 前綴。因此,舉例來說,一個名為 X-Bender 的標頭會對應到 METAHTTP_X_BENDER

請注意,runserver 會移除名稱中帶有底線的所有標頭,因此您不會在 META 中看到它們。這可以防止基於 WSGI 環境變數中底線和破折號都被正規化為底線的模糊性,而導致的標頭偽造。它符合像 Nginx 和 Apache 2.4+ 等 Web 伺服器的行為。

HttpRequest.headers 是一種更簡單的方式來存取所有帶有 HTTP 前綴的標頭,以及 CONTENT_LENGTHCONTENT_TYPE

HttpRequest.headers[原始碼]

一個不區分大小寫的、類似字典的物件,可讓您存取請求中所有帶有 HTTP 前綴的標頭(加上 Content-LengthContent-Type)。

每個標頭的名稱在顯示時都使用首字母大寫的樣式(例如 User-Agent)。您可以不區分大小寫地存取標頭。

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> "User-Agent" in request.headers
True
>>> "user-agent" in request.headers
True

>>> request.headers["User-Agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers["user-agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get("User-Agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get("user-agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

例如,在 Django 範本中使用時,也可以使用底線代替連字符號來查詢標頭。

{{ request.headers.user_agent }}
HttpRequest.resolver_match

一個 ResolverMatch 的實例,表示解析後的 URL。 此屬性僅在 URL 解析發生後才會設定,這表示它在所有視圖中都可用,但在 URL 解析發生之前執行的中介軟體中不可用(但您可以在 process_view() 中使用它)。

由應用程式程式碼設定的屬性

Django 本身不會設定這些屬性,但如果您的應用程式設定了這些屬性,則會使用它們。

HttpRequest.current_app

url 範本標籤會將其值用作 reverse()current_app 引數。

HttpRequest.urlconf

這將用作當前請求的根 URLconf,覆蓋 ROOT_URLCONF 設定。 請參閱 Django 如何處理請求 以瞭解詳細資訊。

urlconf 可以設定為 None 以還原先前中介軟體所做的任何變更,並返回使用 ROOT_URLCONF

HttpRequest.exception_reporter_filter

這將用於替代目前請求的 DEFAULT_EXCEPTION_REPORTER_FILTER。請參閱 自訂錯誤報告 以瞭解詳細資訊。

HttpRequest.exception_reporter_class

這將用於替代目前請求的 DEFAULT_EXCEPTION_REPORTER。請參閱 自訂錯誤報告 以瞭解詳細資訊。

由中介軟體設定的屬性

Django 的 contrib 應用程式中包含的一些中介軟體會在請求上設定屬性。如果您在請求上沒有看到該屬性,請務必將適當的中介軟體類別列在 MIDDLEWARE 中。

HttpRequest.session

來自 SessionMiddleware:一個可讀寫的、類似字典的物件,表示目前的會話。

HttpRequest.site

來自 CurrentSiteMiddleware:一個 SiteRequestSite 的實例,由 get_current_site() 返回,表示目前網站。

HttpRequest.user

來自 AuthenticationMiddleware:一個 AUTH_USER_MODEL 的實例,表示目前已登入的使用者。如果使用者目前未登入,則 user 將會設定為 AnonymousUser 的實例。您可以使用 is_authenticated 來區分它們,如下所示:

if request.user.is_authenticated:
    ...  # Do something for logged-in users.
else:
    ...  # Do something for anonymous users.

auser() 方法執行相同的操作,但可以在非同步環境中使用。

方法

HttpRequest.auser()
Django 5.0 的新增功能。

來自 AuthenticationMiddleware:協程。回傳一個代表目前已登入使用者的 AUTH_USER_MODEL 實例。如果使用者目前未登入,auser 會回傳一個 AnonymousUser 實例。這與 user 屬性類似,但它可在非同步環境中運作。

HttpRequest.get_host()[原始碼]

依序使用 HTTP_X_FORWARDED_HOST (如果 USE_X_FORWARDED_HOST 已啟用)和 HTTP_HOST 標頭中的資訊,回傳請求的原始主機。如果它們沒有提供值,該方法會結合 SERVER_NAMESERVER_PORT,如 PEP 3333 中所詳述。

範例:"127.0.0.1:8000"

如果主機不在 ALLOWED_HOSTS 中,或者網域名稱根據 RFC 1034/1035 無效,則會引發 django.core.exceptions.DisallowedHost

注意

當主機位於多個代理伺服器之後時,get_host() 方法會失敗。一種解決方案是使用中介軟體來重寫代理伺服器標頭,如下面的範例所示

class MultipleProxyMiddleware:
    FORWARDED_FOR_FIELDS = [
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED_HOST",
        "HTTP_X_FORWARDED_SERVER",
    ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """
        Rewrites the proxy headers so that only the most
        recent proxy is used.
        """
        for field in self.FORWARDED_FOR_FIELDS:
            if field in request.META:
                if "," in request.META[field]:
                    parts = request.META[field].split(",")
                    request.META[field] = parts[-1].strip()
        return self.get_response(request)

此中介軟體應放置在任何其他依賴 get_host() 值的其他中介軟體之前 - 例如,CommonMiddlewareCsrfViewMiddleware

HttpRequest.get_port()[原始碼]

依序使用 HTTP_X_FORWARDED_PORT (如果 USE_X_FORWARDED_PORT 已啟用)和 SERVER_PORT META 變數中的資訊,回傳請求的原始埠。

HttpRequest.get_full_path()[原始碼]

回傳 path,加上附加的查詢字串(如果有的話)。

範例:"/music/bands/the_beatles/?print=true"

HttpRequest.get_full_path_info()[原始碼]

get_full_path() 類似,但使用 path_info 而不是 path

範例:"/minfo/music/bands/the_beatles/?print=true"

HttpRequest.build_absolute_uri(location=None)[原始碼]

回傳 location 的絕對 URI 格式。如果未提供 location,location 將會設定為 request.get_full_path()

如果 location 已經是絕對 URI,則不會變更。否則,絕對 URI 會使用此請求中可用的伺服器變數建構。例如

>>> request.build_absolute_uri()
'https://example.com/music/bands/the_beatles/?print=true'
>>> request.build_absolute_uri("/bands/")
'https://example.com/bands/'
>>> request.build_absolute_uri("https://example2.com/bands/")
'https://example2.com/bands/'

注意

不建議在同一個網站上混合使用 HTTP 和 HTTPS,因此 build_absolute_uri() 將永遠使用目前請求所使用的相同協定產生絕對 URI。如果您需要將使用者重新導向至 HTTPS,最好讓您的網頁伺服器將所有 HTTP 流量重新導向至 HTTPS。

回傳簽名 cookie 的值,如果簽名不再有效,則引發 django.core.signing.BadSignature 例外。如果您提供 default 引數,則會抑制例外,並改為回傳該預設值。

可選的 salt 引數可用於提供額外的保護,以防止對您的密鑰進行暴力攻擊。如果提供,將會根據附加到 cookie 值的簽名時間戳記檢查 max_age 引數,以確保 cookie 不超過 max_age 秒。

例如

>>> request.get_signed_cookie("name")
'Tony'
>>> request.get_signed_cookie("name", salt="name-salt")
'Tony' # assuming cookie was set using the same salt
>>> request.get_signed_cookie("nonexistent-cookie")
KeyError: 'nonexistent-cookie'
>>> request.get_signed_cookie("nonexistent-cookie", False)
False
>>> request.get_signed_cookie("cookie-that-was-tampered-with")
BadSignature: ...
>>> request.get_signed_cookie("name", max_age=60)
SignatureExpired: Signature age 1677.3839159 > 60 seconds
>>> request.get_signed_cookie("name", False, max_age=60)
False

有關更多資訊,請參閱 密碼編譯簽名

HttpRequest.is_secure()[原始碼]

如果請求是安全的,則回傳 True;也就是說,如果它是使用 HTTPS 發出的。

HttpRequest.accepts(mime_type)[原始碼]

如果請求的 Accept 標頭符合 mime_type 引數,則回傳 True

>>> request.accepts("text/html")
True

大多數瀏覽器預設傳送 Accept: */*,因此這會針對所有內容類型回傳 True。在 API 請求中設定明確的 Accept 標頭,對於僅針對這些消費者回傳不同的內容類型可能很有用。請參閱 內容協商範例,了解如何使用 accepts() 向 API 消費者回傳不同的內容。

如果回應根據 Accept 標頭的內容而有所不同,並且您正在使用某種形式的快取,例如 Django 的 快取 中介軟體,您應該使用 vary_on_headers('Accept') 裝飾檢視,以便正確快取回應。

HttpRequest.read(size=None)[原始碼]
HttpRequest.readline()[原始碼]
HttpRequest.readlines()[原始碼]
HttpRequest.__iter__()[原始碼]

這些方法為從 HttpRequest 實例讀取資料提供了類似檔案的介面。這使得以串流方式處理傳入的請求成為可能。一個常見的用例是使用迭代解析器處理大型 XML 負載,而無需在記憶體中構建整個 XML 樹。

有了這個標準介面,HttpRequest 實例可以直接傳遞給 XML 解析器,例如 ElementTree

import xml.etree.ElementTree as ET

for element in ET.iterparse(request):
    process(element)

QueryDict 物件

class QueryDict[原始碼]

HttpRequest 物件中,GETPOST 屬性是 django.http.QueryDict 的實例,這是一個類似字典的類,專門用於處理同一個鍵的多個值。這是必要的,因為某些 HTML 表單元素,特別是 <select multiple>,會傳遞同一個鍵的多個值。

當在正常的請求/回應週期中訪問時,request.POSTrequest.GET 中的 QueryDict 將是不可變的。要取得可變的版本,您需要使用 QueryDict.copy()

方法

QueryDict 實作了所有標準的字典方法,因為它是字典的子類。此處概述了例外情況。

QueryDict.__init__(query_string=None, mutable=False, encoding=None)[原始碼]

根據 query_string 實例化一個 QueryDict 物件。

>>> QueryDict("a=1&a=2&c=3")
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

如果未傳入 query_string,則產生的 QueryDict 將為空(它將沒有鍵或值)。

您遇到的大多數 QueryDict,特別是在 request.POSTrequest.GET 中的,將是不可變的。如果您自己實例化一個,您可以透過將 mutable=True 傳遞給其 __init__() 來使其可變。

用於設定鍵和值字串將從 encoding 轉換為 str。如果未設定 encoding,則預設為 DEFAULT_CHARSET

classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)[原始碼]

使用來自 iterable 的鍵和每個等於 value 的值建立一個新的 QueryDict。例如

>>> QueryDict.fromkeys(["a", "a", "b"], value="val")
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>
QueryDict.__getitem__(key)

傳回給定鍵的值。如果鍵有多個值,則傳回最後一個值。如果該鍵不存在,則引發 django.utils.datastructures.MultiValueDictKeyError。(這是 Python 標準 KeyError 的子類,因此您可以堅持捕捉 KeyError。)

QueryDict.__setitem__(key, value)[原始碼]

將給定的鍵設定為 [value](一個列表,其唯一元素是 value)。請注意,此函式,與其他具有副作用的字典函式一樣,只能在可變的 QueryDict 上呼叫(例如透過 QueryDict.copy() 建立的)。

QueryDict.__contains__(key)

如果設定了給定的鍵,則傳回 True。這讓您可以執行,例如,if "foo" in request.GET

QueryDict.get(key, default=None)

使用與 __getitem__() 相同的邏輯,並在鍵不存在時提供傳回預設值的掛鉤。

QueryDict.setdefault(key, default=None)[原始碼]

dict.setdefault() 類似,但內部使用 __setitem__()

QueryDict.update(other_dict)

接受 QueryDict 或字典。類似於 dict.update(),但它是附加到目前的字典項目,而不是取代它們。例如:

>>> q = QueryDict("a=1", mutable=True)
>>> q.update({"a": "2"})
>>> q.getlist("a")
['1', '2']
>>> q["a"]  # returns the last
'2'
QueryDict.items()

類似於 dict.items(),但此方法使用與 __getitem__() 相同的最後值邏輯,並返回一個迭代器物件,而不是視圖物件。例如:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.items())
[('a', '3')]
QueryDict.values()

類似於 dict.values(),但此方法使用與 __getitem__() 相同的最後值邏輯,並返回一個迭代器,而不是視圖物件。例如:

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.values())
['3']

此外,QueryDict 還有以下方法:

QueryDict.copy()[原始碼]

使用 copy.deepcopy() 返回物件的副本。即使原始物件不可變,此副本也將是可變的。

QueryDict.getlist(key, default=None)

返回具有請求鍵的資料列表。如果鍵不存在且 defaultNone,則返回空列表。除非提供的預設值不是列表,否則保證返回列表。

QueryDict.setlist(key, list_)[原始碼]

將給定的鍵設定為 list_(與 __setitem__() 不同)。

QueryDict.appendlist(key, item)[原始碼]

將一個項目附加到與鍵關聯的內部列表。

QueryDict.setlistdefault(key, default_list=None)[原始碼]

類似於 setdefault(),但它接受值列表,而不是單個值。

QueryDict.lists()

類似於 items(),但它包含字典中每個成員的所有值,以列表形式呈現。例如:

>>> q = QueryDict("a=1&a=2&a=3")
>>> q.lists()
[('a', ['1', '2', '3'])]
QueryDict.pop(key)[原始碼]

返回給定鍵的值列表,並將其從字典中刪除。如果鍵不存在,則引發 KeyError。例如:

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.pop("a")
['1', '2', '3']
QueryDict.popitem()[原始碼]

刪除字典中的任意成員(因為沒有排序的概念),並返回一個包含鍵和該鍵的所有值列表的雙值元組。在空字典上調用時,會引發 KeyError。例如:

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])
QueryDict.dict()

返回 QueryDictdict 表示形式。對於 QueryDict 中的每個 (key, list) 對,dict 將具有 (key, item),其中 item 是列表中的一個元素,使用與 QueryDict.__getitem__() 相同的邏輯。

>>> q = QueryDict("a=1&a=3&a=5")
>>> q.dict()
{'a': '5'}
QueryDict.urlencode(safe=None)[原始碼]

以查詢字串格式返回資料字串。例如:

>>> q = QueryDict("a=2&b=3&b=5")
>>> q.urlencode()
'a=2&b=3&b=5'

使用 safe 參數傳遞不需要編碼的字元。例如:

>>> q = QueryDict(mutable=True)
>>> q["next"] = "/a&b/"
>>> q.urlencode(safe="/")
'next=/a%26b/'

HttpResponse 物件

class HttpResponse[原始碼]

與 Django 自動建立的 HttpRequest 物件相反,HttpResponse 物件是您的責任。您編寫的每個視圖都負責實例化、填充和返回 HttpResponse

HttpResponse 類別位於 django.http 模組中。

用法

傳遞字串

典型的用法是將頁面的內容作為字串、位元組字串或 memoryview 傳遞給 HttpResponse 建構子

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")
>>> response = HttpResponse(b"Bytestrings are also accepted.")
>>> response = HttpResponse(memoryview(b"Memoryview as well."))

但如果您想要漸進式地新增內容,您可以將 response 作為類似檔案的物件使用

>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

傳遞迭代器

最後,您可以將迭代器而不是字串傳遞給 HttpResponseHttpResponse 將立即消耗迭代器,將其內容儲存為字串,然後將其丟棄。具有 close() 方法的物件(例如檔案和產生器)會立即關閉。

如果您需要從迭代器將回應串流到用戶端,則必須改用 StreamingHttpResponse 類別。

設定標頭欄位

若要在回應中設定或刪除標頭欄位,請使用 HttpResponse.headers

>>> response = HttpResponse()
>>> response.headers["Age"] = 120
>>> del response.headers["Age"]

您也可以像操作字典一樣操作標頭

>>> response = HttpResponse()
>>> response["Age"] = 120
>>> del response["Age"]

這會代理到 HttpResponse.headers,並且是 HttpResponse 提供的原始介面。

當使用此介面時,與字典不同,如果標頭欄位不存在,del 不會引發 KeyError

您也可以在實例化時設定標頭

>>> response = HttpResponse(headers={"Age": 120})

為了設定 Cache-ControlVary 標頭欄位,建議使用 patch_cache_control()patch_vary_headers() 方法,這些方法來自 django.utils.cache,因為這些欄位可以有多個以逗號分隔的值。「patch」方法可確保其他值(例如由中介軟體添加的值)不會被移除。

HTTP 標頭欄位不能包含換行符號。嘗試設定包含換行字元(CR 或 LF)的標頭欄位將會引發 BadHeaderError

告訴瀏覽器將回應視為檔案附件

若要告訴瀏覽器將回應視為檔案附件,請設定 Content-TypeContent-Disposition 標頭。例如,這是一個您可能如何返回 Microsoft Excel 試算表的方式:

>>> response = HttpResponse(
...     my_data,
...     headers={
...         "Content-Type": "application/vnd.ms-excel",
...         "Content-Disposition": 'attachment; filename="foo.xls"',
...     },
... )

關於 Content-Disposition 標頭,並沒有任何 Django 特有的內容,但它很容易忘記語法,所以我們在這裡包含了它。

屬性

HttpResponse.content[原始碼]

一個表示內容的位元組字串,如果必要,會從字串編碼。

HttpResponse.cookies

一個 http.cookies.SimpleCookie 物件,其中包含回應中包含的 cookies。

HttpResponse.headers

一個不區分大小寫、類似字典的物件,提供對回應中所有 HTTP 標頭(Set-Cookie 標頭除外)的介面。請參閱設定標頭欄位HttpResponse.cookies

HttpResponse.charset

一個字串,表示回應將被編碼的字元集。如果未在 HttpResponse 實例化時給定,它將從 content_type 中提取,如果該操作不成功,則將使用 DEFAULT_CHARSET 設定。

HttpResponse.status_code

回應的 HTTP 狀態碼

除非明確設定 reason_phrase,否則在建構函式外部修改 status_code 的值也會修改 reason_phrase 的值。

HttpResponse.reason_phrase

回應的 HTTP 原因短語。它使用 HTTP 標準的預設原因短語。

除非明確設定,否則 reason_phrasestatus_code 的值決定。

HttpResponse.streaming

這永遠是 False

此屬性存在是為了讓中介軟體可以將串流回應與一般回應區別對待。

HttpResponse.closed

如果回應已關閉,則為 True

方法

HttpResponse.__init__(content=b'', content_type=None, status=200, reason=None, charset=None, headers=None)[原始碼]

使用給定的頁面內容、內容類型和標頭來實例化 HttpResponse 物件。

content 最常見的是迭代器、位元組字串、 memoryview 或字串。其他類型將透過編碼它們的字串表示形式來轉換為位元組字串。迭代器應返回字串或位元組字串,這些字串或位元組字串將被連接在一起以形成回應的內容。

content_type 是 MIME 類型,可選擇性地由字元集編碼完成,並用於填寫 HTTP Content-Type 標頭。如果未指定,則由 'text/html'DEFAULT_CHARSET 設定組成,預設值為: "text/html; charset=utf-8"

status 是回應的 HTTP 狀態碼。您可以使用 Python 的 http.HTTPStatus 來表示有意義的別名,例如 HTTPStatus.NO_CONTENT

reason 是 HTTP 回應短語。如果未提供,將使用預設短語。

charset 是回應將被編碼的字元集。如果未給定,它將從 content_type 中提取,如果該操作不成功,則將使用 DEFAULT_CHARSET 設定。

headers 是回應的 HTTP 標頭 dict

HttpResponse.__setitem__(header, value)

將給定的標頭名稱設定為給定的值。 headervalue 都應該是字串。

HttpResponse.__delitem__(header)

刪除具有給定名稱的標頭。如果標頭不存在,則會無聲地失敗。不區分大小寫。

HttpResponse.__getitem__(header)

返回給定標頭名稱的值。不區分大小寫。

HttpResponse.get(header, alternate=None)

返回給定標頭的值,如果標頭不存在,則返回 alternate

HttpResponse.has_header(header)

根據給定名稱的標頭進行不區分大小寫的檢查,返回 TrueFalse

HttpResponse.items()

作用類似於回應中 HTTP 標頭的 dict.items()

HttpResponse.setdefault(header, value)

設定標頭,除非它已經被設定。

設定 cookie。參數與 Python 標準函式庫中 Morsel cookie 物件中的相同。

  • max_age 應該是一個 timedelta 物件、一個整數秒數,或 None(預設值),如果 cookie 的有效期應僅限於用戶端瀏覽器工作階段。如果未指定 expires,則將會計算。

  • expires 應該是一個格式為 "Wdy, DD-Mon-YY HH:MM:SS GMT" 的字串,或是一個 UTC 的 datetime.datetime 物件。如果 expires 是一個 datetime 物件,則將會計算 max_age

  • 如果您想設定跨網域 cookie,請使用 domain。例如,domain="example.com" 將會設定一個可由網域 www.example.com、blog.example.com 等讀取的 cookie。否則,cookie 將僅能由設定它的網域讀取。

  • 如果您希望 cookie 僅在以 https 方案發出請求時才傳送到伺服器,請使用 secure=True

  • 如果您想要防止用戶端 JavaScript 存取 cookie,請使用 httponly=True

    HttpOnly 是 Set-Cookie HTTP 回應標頭中包含的一個旗標。它是 RFC 6265 cookie 標準的一部分,並且可以作為降低用戶端腳本存取受保護 cookie 資料風險的有效方式。

  • 使用 samesite='Strict'samesite='Lax' 來告知瀏覽器在執行跨域請求時不要傳送此 cookie。SameSite 並非所有瀏覽器都支援,因此它不能取代 Django 的 CSRF 保護,而是一種深度防禦措施。

    使用 samesite='None' (字串) 明確聲明此 cookie 會隨著所有同網域和跨網域請求傳送。

警告

RFC 6265 指出使用者代理程式應支援至少 4096 個位元組的 cookie。對於許多瀏覽器來說,這也是最大尺寸。如果嘗試儲存超過 4096 個位元組的 cookie,Django 不會引發例外,但許多瀏覽器將無法正確設定 cookie。

類似於 set_cookie(),但在設定 cookie 之前會先對其進行密碼簽署。與 HttpRequest.get_signed_cookie() 搭配使用。您可以使用可選的 salt 引數來增加金鑰強度,但您需要記得將其傳遞給對應的 HttpRequest.get_signed_cookie() 呼叫。

刪除具有給定金鑰的 cookie。如果金鑰不存在,則會靜默失敗。

由於 cookie 的運作方式,pathdomain 應該與您在 set_cookie() 中使用的值相同 – 否則可能無法刪除 cookie。

HttpResponse.close()

此方法會在請求結束時由 WSGI 伺服器直接呼叫。

HttpResponse.write(content)[原始碼]

此方法使 HttpResponse 實例成為類似檔案的物件。

HttpResponse.flush()

此方法使 HttpResponse 實例成為類似檔案的物件。

HttpResponse.tell()[原始碼]

此方法使 HttpResponse 實例成為類似檔案的物件。

HttpResponse.getvalue()[原始碼]

傳回 HttpResponse.content 的值。此方法使 HttpResponse 實例成為類似串流的物件。

HttpResponse.readable()

永遠為 False。此方法使 HttpResponse 實例成為類似串流的物件。

HttpResponse.seekable()

永遠為 False。此方法使 HttpResponse 實例成為類似串流的物件。

HttpResponse.writable() [原始碼]

永遠為 True。這個方法使 HttpResponse 實例成為類似串流的物件。

HttpResponse.writelines(lines) [原始碼]

將一串行寫入回應中。不會加入行分隔符號。這個方法使 HttpResponse 實例成為類似串流的物件。

HttpResponse 子類別

Django 包含許多處理不同 HTTP 回應類型的 HttpResponse 子類別。如同 HttpResponse,這些子類別位於 django.http 中。

class HttpResponseRedirect[原始碼]

建構子的第一個參數是必要的 - 要重新導向的路徑。這可以是完整合格的 URL (例如 'https://www.yahoo.com/search/')、沒有網域的絕對路徑 (例如 '/search/'),甚至是相對路徑 (例如 'search/')。在最後一種情況下,客戶端瀏覽器將根據目前路徑重新建構完整的 URL。請參閱 HttpResponse 以取得其他可選的建構子參數。請注意,這會傳回 HTTP 狀態碼 302。

url

這個唯讀屬性代表回應將重新導向的 URL (相當於 Location 回應標頭)。

class HttpResponsePermanentRedirect[原始碼]

HttpResponseRedirect 類似,但它會傳回永久重新導向 (HTTP 狀態碼 301),而不是「找到」的重新導向 (狀態碼 302)。

class HttpResponseNotModified[原始碼]

建構子不接受任何參數,並且不應將任何內容加入此回應。使用這個來表示頁面自使用者上次請求後未被修改 (狀態碼 304)。

class HttpResponseBadRequest[原始碼]

作用方式與 HttpResponse 完全相同,但使用 400 狀態碼。

class HttpResponseNotFound[原始碼]

作用方式與 HttpResponse 完全相同,但使用 404 狀態碼。

class HttpResponseForbidden[原始碼]

作用方式與 HttpResponse 完全相同,但使用 403 狀態碼。

class HttpResponseNotAllowed[原始碼]

HttpResponse 類似,但使用 405 狀態碼。建構子的第一個參數是必要的:允許的方法清單 (例如 ['GET', 'POST'])。

class HttpResponseGone[原始碼]

作用方式與 HttpResponse 完全相同,但使用 410 狀態碼。

class HttpResponseServerError[原始碼]

作用方式與 HttpResponse 完全相同,但使用 500 狀態碼。

注意

如果 HttpResponse 的自訂子類別實作 render 方法,Django 會將其視為模擬 SimpleTemplateResponse,而 render 方法本身必須傳回有效的回應物件。

自訂回應類別

如果您發現自己需要 Django 沒有提供的回應類別,您可以使用 http.HTTPStatus 來建立。例如

from http import HTTPStatus
from django.http import HttpResponse


class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

JsonResponse 物件

class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs) [原始碼]

一個 HttpResponse 子類別,有助於建立 JSON 編碼的回應。它繼承了其父類別的大部分行為,但有一些差異

其預設 Content-Type 標頭設定為 application/json

第一個參數 data 應為 dict 實例。如果 safe 參數設定為 False (請參閱下方),它可以是任何 JSON 可序列化的物件。

encoder,預設為 django.core.serializers.json.DjangoJSONEncoder,將用於序列化資料。請參閱 JSON 序列化 以取得關於此序列化器的更多詳細資訊。

safe 布林參數預設值為 True。如果設定為 False,則可以傳遞任何物件進行序列化(否則只允許 dict 實例)。如果 safeTrue 且傳遞非 dict 物件作為第一個參數,則會引發 TypeError

json_dumps_params 參數是一個字典,其中包含要傳遞給用於產生回應的 json.dumps() 呼叫的關鍵字引數。

使用方式

典型用法可能如下所示

>>> from django.http import JsonResponse
>>> response = JsonResponse({"foo": "bar"})
>>> response.content
b'{"foo": "bar"}'

序列化非字典物件

為了序列化 dict 以外的物件,您必須將 safe 參數設定為 False

>>> response = JsonResponse([1, 2, 3], safe=False)

若沒有傳遞 safe=False,則會引發 TypeError

請注意,基於 dict 物件的 API 更具可擴展性、彈性,且更容易維持向前相容性。因此,您應避免在 JSON 編碼的回應中使用非 dict 物件。

警告

ECMAScript 第 5 版之前,可以毒害 JavaScript 的 Array 建構函式。基於此原因,Django 預設不允許將非 dict 物件傳遞給 JsonResponse 建構函式。然而,大多數現代瀏覽器都實作了 ECMAScript 5,它移除了這個攻擊途徑。因此,可以停用此安全預防措施。

變更預設 JSON 編碼器

如果您需要使用不同的 JSON 編碼器類別,您可以將 encoder 參數傳遞給建構函式方法

>>> response = JsonResponse(data, encoder=MyJSONEncoder)

StreamingHttpResponse 物件

class StreamingHttpResponse[來源]

StreamingHttpResponse 類別用於將回應從 Django 串流到瀏覽器。

進階用法

StreamingHttpResponse 有點進階,因為了解您是在 WSGI 下同步服務應用程式,還是 ASGI 下非同步服務應用程式,並適當調整您的用法非常重要。

請仔細閱讀這些注意事項。

在 WSGI 下使用 StreamingHttpResponse 的一個範例是在產生回應時耗時太長或使用太多記憶體時串流內容。例如,它對於產生大型 CSV 檔案很有用。

然而,這樣做時需要考慮效能。在 WSGI 下,Django 專為短暫的請求而設計。串流回應將在整個回應期間佔用一個 worker 程序。這可能會導致效能不佳。

一般來說,您會在請求-回應週期之外執行耗時的任務,而不是求助於串流回應。

然而,在 ASGI 下服務時,StreamingHttpResponse 不需要停止其他請求,才能在等待 I/O 時被服務。這為串流內容的長期請求和實作諸如長輪詢和伺服器發送事件等模式開啟了可能性。

即使在 ASGI 下,也請注意,StreamingHttpResponse 僅應在絕對需要的情況下使用,即在將資料傳輸到客戶端之前不會迭代整個內容。由於無法存取內容,許多中介軟體無法正常運作。例如,無法為串流回應產生 ETagContent-Length 標頭。

StreamingHttpResponse 不是 HttpResponse 的子類別,因為它的 API 略有不同。但是,它幾乎完全相同,具有以下顯著差異

  • 應給定一個產生位元組字串、memoryview 或字串作為內容的迭代器。在 WSGI 下服務時,這應該是一個同步迭代器。在 ASGI 下服務時,則應該是一個非同步迭代器。

  • 您無法存取其內容,除非迭代回應物件本身。這應該僅在將回應傳回給客戶端時發生:您不應該自己迭代回應。

    在 WSGI 下,回應將同步迭代。在 ASGI 下,回應將非同步迭代。(這就是為什麼迭代器類型必須與您使用的協定相符的原因。)

    為了避免崩潰,不正確的迭代器類型將在迭代期間對應到正確的類型,並且會引發警告,但為了做到這一點,迭代器必須完全消耗,這就失去了使用 StreamingHttpResponse 的目的。

  • 它沒有 content 屬性。相反,它有一個 streaming_content 屬性。這可以在中介軟體中使用以包裝回應可迭代對象,但不應消耗它。

  • 您不能使用類檔案物件 tell()write() 方法。這樣做會引發例外狀況。

HttpResponseBase 基類在 HttpResponseStreamingHttpResponse 之間是通用的。

屬性

StreamingHttpResponse.streaming_content[來源]

回應內容的迭代器,根據 HttpResponse.charset 編碼為位元組字串。

StreamingHttpResponse.status_code

回應的 HTTP 狀態碼

除非明確設定 reason_phrase,否則在建構函式之外修改 status_code 的值也會修改 reason_phrase 的值。

StreamingHttpResponse.reason_phrase

回應的 HTTP 原因短語。它使用 HTTP 標準的預設原因短語。

除非明確設定,否則 reason_phrasestatus_code 的值決定。

StreamingHttpResponse.streaming

這總是 True

StreamingHttpResponse.is_async

布林值,表示 StreamingHttpResponse.streaming_content 是否為非同步迭代器。

這對於需要包裝 StreamingHttpResponse.streaming_content 的中介軟體很有用。

處理斷線

Django 5.0 的新增功能。

如果用戶端在串流回應期間斷線,Django 將會取消處理回應的協程。 如果您想手動清理資源,可以透過捕捉 asyncio.CancelledError 來完成。

async def streaming_response():
    try:
        # Do some work here
        async for chunk in my_streaming_iterator():
            yield chunk
    except asyncio.CancelledError:
        # Handle disconnect
        ...
        raise


async def my_streaming_view(request):
    return StreamingHttpResponse(streaming_response())

此範例僅說明如何在回應串流時處理用戶端斷線。 如果您在檢視中執行長時間執行的操作,然後才返回 StreamingHttpResponse 物件,您可能還想在檢視本身中處理斷線

FileResponse 物件

class FileResponse(open_file, as_attachment=False, filename='', **kwargs)[原始碼]

FileResponseStreamingHttpResponse 的子類別,專為二進位檔案優化。 如果 wsgi 伺服器提供,它會使用 wsgi.file_wrapper,否則它會以小區塊串流輸出檔案。

如果 as_attachment=True,則 Content-Disposition 標頭會設定為 attachment,這會要求瀏覽器將該檔案提供給使用者作為下載。 否則,只有在有檔案名稱可用的情況下,才會設定值為 inline (瀏覽器預設值) 的 Content-Disposition 標頭。

如果 open_file 沒有名稱,或 open_file 的名稱不適當,請使用 filename 參數提供自訂檔案名稱。 請注意,如果您傳遞類似 io.BytesIO 的類檔案物件,則您有責任在將其傳遞給 FileResponse 之前 seek() 它。

當可以從 open_file 的內容猜測出時,Content-Length 標頭會自動設定。

當可以從 filenameopen_file 的名稱猜測出時,Content-Type 標頭會自動設定。

FileResponse 接受任何具有二進位內容的類檔案物件,例如以二進位模式開啟的檔案,如下所示

>>> from django.http import FileResponse
>>> response = FileResponse(open("myfile.png", "rb"))

該檔案將會自動關閉,因此請勿使用內容管理器開啟它。

在 ASGI 下使用

Python 的檔案 API 是同步的。 這表示為了在 ASGI 下提供檔案,必須完全消耗檔案。

為了非同步串流檔案,您需要使用提供非同步檔案 API 的第三方套件,例如 aiofiles

方法

FileResponse.set_headers(open_file)[原始碼]

此方法會在回應初始化期間自動呼叫,並根據 open_file 設定各種標頭 (Content-LengthContent-TypeContent-Disposition)。

HttpResponseBase 類別

class HttpResponseBase[原始碼]

HttpResponseBase 類別是所有 Django 回應的共同類別。 它不應該用於直接建立回應,但它對於類型檢查很有用。

返回頂端