Django 工具¶
此文件涵蓋 django.utils
中所有穩定的模組。django.utils
中的大多數模組都設計為內部使用,只有以下部分可以被視為穩定,因此根據內部發布棄用政策向後相容。
django.utils.cache
¶
此模組包含用於控制 HTTP 快取的輔助函數。它透過管理回應的 Vary
標頭來實現。它包含直接修補回應物件標頭的函數,以及將函數更改為自行進行標頭修補的裝飾器。
關於 Vary
標頭的資訊,請參閱RFC 9110 第 12.5.5 節。
基本上,Vary
HTTP 標頭定義快取在建構其快取鍵時應考慮哪些標頭。對於在 Vary
中命名的標頭,具有相同路徑但標頭內容不同的請求需要取得不同的快取鍵,以防止傳遞錯誤的內容。
例如,國際化中介軟體需要根據 Accept-language
標頭來區分快取。
- patch_cache_control(response, **kwargs)[來源]¶
此函數透過將所有關鍵字參數新增至
Cache-Control
標頭來修補它。轉換如下所有關鍵字參數名稱都轉換為小寫,底線轉換為連字號。
如果參數的值為
True
(精確地為True
,而不僅僅是 true 值),則僅將參數名稱新增至標頭。所有其他參數都會在使用
str()
轉換後,連同它們的值一起新增。
- patch_response_headers(response, cache_timeout=None)[來源]¶
將一些有用的標頭新增至指定的
HttpResponse
物件Expires
Cache-Control
只有在尚未設定時,才會新增每個標頭。
cache_timeout
以秒為單位。CACHE_MIDDLEWARE_SECONDS
設定預設使用。
- add_never_cache_headers(response)[來源]¶
將
Expires
標頭新增至目前的日期/時間。將
Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private
標頭新增至回應,表示頁面不應被快取。只有在尚未設定時,才會新增每個標頭。
- patch_vary_headers(response, newheaders)[來源]¶
在指定的
HttpResponse
物件中新增 (或更新)Vary
標頭。newheaders
是應在Vary
中的標頭名稱列表。如果標頭包含星號,則Vary
標頭將由單個星號'*'
組成,根據RFC 9110 第 12.5.5 節。否則,Vary
中的現有標頭不會移除。
django.utils.dateparse
¶
在此模組中定義的函數共用以下屬性
它們接受 ISO 8601 日期/時間格式 (或某些接近的替代格式) 的字串,並從 Python
datetime
模組中的對應類別傳回物件。如果它們的輸入格式正確,但不是有效的日期或時間,則它們會引發
ValueError
。如果格式完全不正確,則它們會傳回
None
。它們在輸入中接受高達皮秒的解析度,但會將其截斷為微秒,因為這是 Python 支援的。
- parse_date(value)[來源]¶
剖析字串並傳回
datetime.date
。
- parse_time(value)[來源]¶
剖析字串並傳回
datetime.time
。不支援 UTC 偏移;如果
value
描述一個 UTC 偏移,則結果為None
。
- parse_datetime(value)[來源]¶
剖析字串並傳回
datetime.datetime
。支援 UTC 偏移;如果
value
描述了一個偏移,則結果的tzinfo
屬性會是一個datetime.timezone
實例。
- parse_duration(value)[原始碼]¶
解析字串並返回
datetime.timedelta
。預期的資料格式為
"DD HH:MM:SS.uuuuuu"
、"DD HH:MM:SS,uuuuuu"
,或者如 ISO 8601 所指定的格式(例如,P4DT1H15M20S
等同於4 1:15:20
)或 PostgreSQL 的日期時間間隔格式(例如,3 days 04:05:06
)。
django.utils.decorators
¶
- method_decorator(decorator, name='')[原始碼]¶
將函式裝飾器轉換為方法裝飾器。它可用於裝飾方法或類別;在後者的情況下,
name
是要裝飾的方法名稱,且為必要參數。decorator
也可以是函式的列表或元組。它們會以相反的順序包裝,因此呼叫順序會是函式在列表/元組中出現的順序。有關使用範例,請參閱 裝飾基於類別的視圖。
- decorator_from_middleware(middleware_class)[原始碼]¶
給定一個中介軟體類別,返回一個視圖裝飾器。這讓您可以在每個視圖的基礎上使用中介軟體功能。中介軟體在建立時不會傳遞任何參數。
它假設中介軟體與舊版 Django 1.9 和更早版本相容(具有如
process_request()
、process_exception()
和process_response()
之類的方法)。
- decorator_from_middleware_with_args(middleware_class)[原始碼]¶
與
decorator_from_middleware
類似,但返回一個接受要傳遞給 middleware_class 的參數的函式。例如,cache_page()
裝飾器是從CacheMiddleware
像這樣建立的cache_page = decorator_from_middleware_with_args(CacheMiddleware) @cache_page(3600) def my_view(request): pass
django.utils.encoding
¶
- smart_str(s, encoding='utf-8', strings_only=False, errors='strict')[原始碼]¶
返回一個代表任意物件
s
的str
物件。使用encoding
編碼器處理位元組字串。如果
strings_only
為True
,則不要轉換(某些)非字串類型的物件。
- force_str(s, encoding='utf-8', strings_only=False, errors='strict')[原始碼]¶
與
smart_str()
類似,不同之處在於惰性實例會解析為字串,而不是保留為惰性物件。如果
strings_only
為True
,則不要轉換(某些)非字串類型的物件。
- smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')[原始碼]¶
返回任意物件
s
的位元組字串版本,並以encoding
中指定的編碼方式進行編碼。如果
strings_only
為True
,則不要轉換(某些)非字串類型的物件。
- force_bytes(s, encoding='utf-8', strings_only=False, errors='strict')[原始碼]¶
與
smart_bytes
類似,不同之處在於惰性實例會解析為位元組字串,而不是保留為惰性物件。如果
strings_only
為True
,則不要轉換(某些)非字串類型的物件。
- iri_to_uri(iri)[原始碼]¶
將國際化資源識別碼 (IRI) 部分轉換為適合包含在 URL 中的 URI 部分。
這是 RFC 3987 第 3.1 節 中的演算法,經過稍微簡化,因為假設輸入為字串而不是任意位元組串流。
採用 IRI(字串或 UTF-8 位元組),並返回包含編碼結果的字串。
- uri_to_iri(uri)[原始碼]¶
將統一資源識別碼轉換為國際化資源識別碼。
這是 RFC 3987 第 3.2 節 中的演算法。
採用 ASCII 位元組的 URI,並返回包含編碼結果的字串。
django.utils.feedgenerator
¶
範例用法
>>> from django.utils import feedgenerator
>>> feed = feedgenerator.Rss201rev2Feed(
... title="Poynter E-Media Tidbits",
... link="https://www.poynter.org/tag/e-media-tidbits/",
... description="A group blog by the sharpest minds in online media/journalism/publishing.",
... language="en",
... )
>>> feed.add_item(
... title="Hello",
... link="https://www.holovaty.com/test/",
... description="Testing.",
... )
>>> with open("test.rss", "w") as fp:
... feed.write(fp, "utf-8")
...
為了簡化產生器的選擇,請使用 feedgenerator.DefaultFeed
,目前為 Rss201rev2Feed
有關不同版本的 RSS 定義,請參閱:https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss
- get_tag_uri(url, date)[原始碼]¶
建立 TagURI。
請參閱 https://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id
Enclosure
¶
RssFeed
¶
Rss201rev2Feed
¶
RssUserland091Feed
¶
Atom1Feed
¶
django.utils.functional
¶
- class cached_property(func)[原始碼]¶
@cached_property
裝飾器會將一個帶有單一self
引數的方法結果快取為屬性。快取結果將在實例存在期間持續有效,因此如果實例被傳遞並隨後調用該函式,則會返回快取結果。考慮一個典型的案例,其中視圖可能需要調用模型的函式來執行一些計算,然後將模型實例放入上下文中,而範本可能會再次調用該函式
# the model class Person(models.Model): def friends(self): # expensive computation ... return friends # in the view: if person.friends(): ...
而在範本中你會看到
{% for friend in person.friends %}
在這裡,
friends()
會被調用兩次。由於視圖和範本中的實例person
是相同的,使用@cached_property
裝飾friends()
方法可以避免這種情況from django.utils.functional import cached_property class Person(models.Model): @cached_property def friends(self): ...
請注意,由於該方法現在是一個屬性,因此在 Python 程式碼中需要以適當的方式存取它
# in the view: if person.friends: ...
快取的值可以像實例的普通屬性一樣對待
# clear it, requiring re-computation next time it's called del person.friends # or delattr(person, "friends") # set a value manually, that will persist on the instance until cleared person.friends = ["Huckleberry Finn", "Tom Sawyer"]
由於 描述器協議 的運作方式,在未被存取的
cached_property
上使用del
(或delattr
) 會引發AttributeError
。除了提供潛在的效能優勢之外,
@cached_property
還可以確保屬性的值在實例的生命週期內不會意外更改。如果方法的計算基於datetime.now()
,或者在同一實例上後續調用方法之間的短暫間隔中,其他進程將變更儲存到資料庫,則可能會發生這種情況。您可以建立方法的快取屬性。例如,如果您有一個耗時的
get_friends()
方法,並希望允許在不檢索快取值的情況下調用它,則可以編寫friends = cached_property(get_friends)
雖然
person.get_friends()
會在每次調用時重新計算朋友,但快取屬性的值將持續存在,直到您如上所述刪除它為止x = person.friends # calls first time y = person.get_friends() # calls again z = person.friends # does not call x is z # is True
- class classproperty(method=None)[原始碼]¶
與
@classmethod
類似,@classproperty
裝飾器會將帶有單一cls
引數的方法結果轉換為可直接從類別存取的屬性。
- keep_lazy(func, *resultclasses)[原始碼]¶
Django 提供了許多實用函式 (特別是在
django.utils
中),這些函式會將字串作為它們的第一個引數,並對該字串執行某些操作。這些函式會被範本篩選器以及其他程式碼直接使用。如果您編寫自己的類似函式並處理翻譯,您將面臨第一個引數是延遲翻譯物件時該怎麼辦的問題。您不希望立即將其轉換為字串,因為您可能會在視圖之外使用此函式 (因此目前執行緒的地區設定將不正確)。
對於這種情況,請使用
django.utils.functional.keep_lazy()
裝飾器。它會修改函式,以便在 如果 使用延遲翻譯作為其引數之一調用時,函式求值會延遲到需要轉換為字串時。例如
from django.utils.functional import keep_lazy, keep_lazy_text def fancy_utility_function(s, *args, **kwargs): # Do some conversion on string 's' ... fancy_utility_function = keep_lazy(str)(fancy_utility_function) # Or more succinctly: @keep_lazy(str) def fancy_utility_function(s, *args, **kwargs): ...
keep_lazy()
裝飾器會採用許多額外的引數 (*args
),指定原始函式可以返回的類型。常見的用例是具有返回文字的函式。對於這些,您可以將str
類型傳遞給keep_lazy
(或使用下一節中描述的keep_lazy_text()
裝飾器)。使用此裝飾器意味著您可以編寫函式並假設輸入是適當的字串,然後在最後新增對延遲翻譯物件的支援。
- keep_lazy_text(func)[原始碼]¶
用於
keep_lazy(str)(func)
的捷徑。如果您有一個返回文字的函式,並且希望能夠接受延遲引數,同時延遲它們的求值,您可以使用此裝飾器
from django.utils.functional import keep_lazy, keep_lazy_text # Our previous example was: @keep_lazy(str) def fancy_utility_function(s, *args, **kwargs): ... # Which can be rewritten as: @keep_lazy_text def fancy_utility_function(s, *args, **kwargs): ...
django.utils.html
¶
通常,您應該使用 Django 的範本建立 HTML,以利用其自動跳脫機制,並在適當的地方使用 django.utils.safestring
中的實用工具。此模組提供了一些用於跳脫 HTML 的其他低層級實用工具。
- escape(text)[原始碼]¶
返回給定的文字,其中已編碼 & 號、引號和角括號,以用於 HTML。輸入會先強制轉換為字串,並且輸出已應用
mark_safe()
。
- format_html(format_string, *args, **kwargs)[原始碼]¶
這與
str.format()
類似,但它適用於建立 HTML 片段。第一個引數format_string
不會被跳脫,但所有其他 args 和 kwargs 會在傳遞至str.format()
之前透過conditional_escape()
傳遞。最後,輸出會應用mark_safe()
。對於建立小型 HTML 片段的情況,此函式比直接使用
%
或str.format()
的字串插補更好,因為它會將跳脫應用於所有引數 - 就像範本系統預設應用跳脫一樣。因此,您應該使用
mark_safe( "%s <b>%s</b> %s" % ( some_html, escape(some_text), escape(some_other_text), ) )
而不是編寫
format_html( "{} <b>{}</b> {}", mark_safe(some_html), some_text, some_other_text, )
它的優點是,您不需要將
escape()
應用於每個引數,並在您忘記一個時冒著程式錯誤和 XSS 漏洞的風險。請注意,雖然此函式使用
str.format()
進行插補,但str.format()
提供的一些格式化選項 (例如數字格式化) 將無法運作,因為所有引數都會透過conditional_escape()
傳遞,該函式 (最終) 會在值上調用force_str()
。自 5.0 版起已棄用:不傳遞 args 或 kwargs 而調用
format_html()
的支援已棄用。
- format_html_join(sep, format_string, args_generator)[原始碼]¶
用於
format_html()
的包裝函式,用於需要使用相同格式字串格式化的引數群組的常見情況,然後使用sep
連接。sep
也會透過conditional_escape()
傳遞。args_generator
應該是一個迭代器,會回傳一連串將傳遞給format_html()
的args
。例如:format_html_join("\n", "<li>{} {}</li>", ((u.first_name, u.last_name) for u in users))
- json_script(value, element_id=None, encoder=None)[原始碼]¶
使用 Unicode 跳脫字元跳脫所有 HTML/XML 特殊字元,因此 value 可以安全地與 JavaScript 一起使用。也會將跳脫的 JSON 包在
<script>
標籤中。如果element_id
參數不是None
,則會將傳遞的 id 給予<script>
標籤。例如:>>> json_script({"hello": "world"}, element_id="hello-data") '<script id="hello-data" type="application/json">{"hello": "world"}</script>'
encoder
預設為django.core.serializers.json.DjangoJSONEncoder
,將用來序列化資料。請參閱 JSON 序列化 以取得更多關於此序列化程式的詳細資訊。
- strip_tags(value)[原始碼]¶
嘗試從字串中移除任何看起來像 HTML 標籤的東西,也就是任何包含在
<>
中的東西。對於產生的字串是否為 HTML 安全,絕對**不**提供任何保證。因此,**絕對不要**在沒有先跳脫的情況下,將
strip_tag
呼叫的結果標記為安全,例如使用escape()
。例如
strip_tags(value)
如果
value
是"<b>Joel</b> <button>is</button> a <span>slug</span>"
,則回傳值將會是"Joel is a slug"
。如果您正在尋找更強大的解決方案,請考慮使用第三方 HTML 清理工具。
- html_safe()[原始碼]¶
類別上的
__html__()
方法可協助非 Django 樣板偵測其輸出不需要 HTML 跳脫的類別。此裝飾器透過將
__str__()
包在mark_safe()
中,在裝飾的類別上定義__html__()
方法。請確保__str__()
方法確實回傳不需要 HTML 跳脫的文字。
django.utils.http
¶
- urlencode(query, doseq=False)[原始碼]¶
Python 的
urllib.parse.urlencode()
函數的一個版本,可以對MultiValueDict
和非字串值進行操作。
- http_date(epoch_seconds=None)[原始碼]¶
格式化時間以符合 HTTP 所指定的 RFC 1123 第 5.2.14 節 日期格式RFC 9110 第 5.6.7 節。
接受以秒為單位表示的浮點數,從 UTC 的 epoch 開始計算,例如
time.time()
的輸出。如果設定為None
,則預設為目前時間。以
Wdy, DD Mon YYYY HH:MM:SS GMT
格式輸出字串。
django.utils.module_loading
¶
用於處理 Python 模組的函數。
django.utils.safestring
¶
用於處理「安全字串」的函數和類別:安全字串是指可以在 HTML 中安全顯示而無需進一步跳脫的字串。將某些東西標記為「安全字串」表示該字串的產生者已將不應由 HTML 引擎解譯的字元(例如「<」)轉換為適當的實體。
- mark_safe(s)[原始碼]¶
明確將字串標記為對 (HTML) 輸出而言是安全的。傳回的物件可以在任何適當使用字串的地方使用。
可以對單一字串多次呼叫。
也可以用作裝飾器。
為了建構 HTML 片段,您通常應該改用
django.utils.html.format_html()
。標記為安全的字串如果在修改後將再次變為不安全。例如:
>>> mystr = "<b>Hello World</b> " >>> mystr = mark_safe(mystr) >>> type(mystr) <class 'django.utils.safestring.SafeString'> >>> mystr = mystr.strip() # removing whitespace >>> type(mystr) <type 'str'>
django.utils.text
¶
- format_lazy(format_string, *args, **kwargs)¶
當
format_string
、args
和/或kwargs
包含惰性物件時,所使用的str.format()
版本。第一個參數是要格式化的字串。例如:from django.utils.text import format_lazy from django.utils.translation import pgettext_lazy urlpatterns = [ path( format_lazy("{person}/<int:pk>/", person=pgettext_lazy("URL", "person")), PersonDetailView.as_view(), ), ]
這個範例允許翻譯人員翻譯 URL 的一部分。如果 “person” 被翻譯成 “persona”,則正規表示式會匹配
persona/(?P<pk>\d+)/$
,例如:persona/5/
。
- slugify(value, allow_unicode=False)[原始碼]¶
將字串轉換為 URL slug 的方式如下:
如果
allow_unicode
為False
(預設值),則轉換為 ASCII。轉換為小寫。
移除非字母數字、底線、連字號或空白的字元。
將任何空白或重複的破折號替換為單個破折號。
移除開頭和結尾的空白、破折號和底線。
例如
>>> slugify(" Joel is a slug ") 'joel-is-a-slug'
如果您想允許 Unicode 字元,請傳遞
allow_unicode=True
。例如:>>> slugify("你好 World", allow_unicode=True) '你好-world'
django.utils.timezone
¶
- get_fixed_timezone(offset)[原始碼]¶
返回一個
tzinfo
實例,該實例表示與 UTC 有固定偏移的時區。offset
是datetime.timedelta
或以分鐘為單位的整數。UTC 以東的時區使用正值,UTC 以西的時區使用負值。
- override(timezone)[原始碼]¶
這是一個 Python 上下文管理器,它在進入時使用
activate()
設定目前時區,並在退出時還原先前作用的時區。如果timezone
參數為None
,則會在進入時使用deactivate()
取消設定目前時區。override
也可以作為函式裝飾器使用。
- localtime(value=None, timezone=None)[原始碼]¶
將帶有時區的
datetime
轉換為不同的時區,預設為目前時區。當省略
value
時,預設為now()
。此函式不適用於天真 (naive) 的 datetime;請改用
make_aware()
。
- localdate(value=None, timezone=None)[原始碼]¶
使用
localtime()
將帶有時區的datetime
轉換為不同時區的date()
,預設為目前時區。當省略
value
時,預設為now()
。此函式不適用於天真的 datetime。
django.utils.translation
¶
有關以下使用方式的完整討論,請參閱翻譯文件。
- gettext_lazy(message)¶
- npgettext(context, singular, plural, number)[原始碼]¶
翻譯
singular
和plural
,並根據number
和context
回傳適當的字串。
- override(language, deactivate=False)[原始碼]¶
一個 Python 上下文管理器,使用
django.utils.translation.activate()
來取得指定語言的翻譯物件,並將其啟用為目前執行緒的翻譯物件。在退出時,會重新啟用先前啟用的語言。或者,如果deactivate
參數為True
,它可以在退出時使用django.utils.translation.deactivate()
停用臨時翻譯。如果將None
作為語言參數傳遞,則會在上下文中啟用一個NullTranslations()
實例。override
也可以作為函式裝飾器使用。
- get_language()[原始碼]¶
返回目前選取的語言代碼。如果翻譯被臨時停用(透過
deactivate_all()
或當None
傳遞給override()
時),則返回None
。
- get_language_from_request(request, check_path=False)[原始碼]¶
分析請求以找出使用者希望系統顯示的語言。僅考慮設定中列出的 LANGUAGES。如果使用者請求一個我們有主要語言的子語言,我們會發送主要語言。
如果
check_path
為True
,則該函數首先檢查請求的 URL 路徑是否以LANGUAGES
設定中列出的語言代碼開始。
- get_supported_language_variant(lang_code, strict=False)[原始碼]¶
如果
lang_code
在LANGUAGES
設定中,則返回lang_code
,可能會選擇更通用的變體。例如,如果lang_code
為'es-ar'
且'es'
在LANGUAGES
中,但'es-ar'
不在,則返回'es'
。lang_code
的最大可接受長度為 500 個字元。如果lang_code
超出此限制且strict
為True
,或者如果沒有通用變體且strict
為False
,則會引發LookupError
。如果
strict
為False
(預設值),當找不到語言代碼或其通用變體時,可能會返回特定於國家/地區的變體。例如,如果只有'es-co'
在LANGUAGES
中,則對於像'es'
和'es-ar'
這樣的lang_code
會返回該值。如果strict=True
,則不會返回這些匹配項。如果找不到任何內容,則引發
LookupError
。在 Django 4.2.15 中變更在舊版本中,處理超過 500 個字元的
lang_code
值而不會引發LookupError
。