---
title: "Django 实用程序"
version: 4.1
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.1/ref/utils/
canonical: https://djangodocs.dev/zh-hans/4.1/ref/utils/
---
# Django 实用程序

本文档涵盖了 `django.utils` 中所有稳定的模块。`django.utils` 中的大部分模块都是为内部使用而设计的，只有以下部分可以被认为是稳定的，因此根据 [内部发布废弃政策](/zh-hans/4.1/internals/release-process/#internal-release-deprecation-policy) 的规定，这些模块可以向后兼容。

## `django.utils.cache`

这个模块包含了控制 HTTP 缓存的辅助函数。它通过管理响应的 `Vary` 头来实现。它包括直接对响应对象的头进行修补的函数，以及改变函数使其自己进行头修补的装饰器。

关于 `Vary` 头的信息，请参见 [**RFC 7231 Section 7.1.4**](https://datatracker.ietf.org/doc/html/rfc7231.html#section-7.1.4)。

本质上，`Vary` HTTP 头定义了缓存在建立缓存密钥时应该考虑哪些头信息。如果请求的路径相同，但 `Vary` 中命名的头内容不同，则需要获得不同的缓存密钥，以防止传递错误的内容。

例如， [国际化](/zh-hans/4.1/topics/i18n/) 中间件需要通过 `Accept-language` 头来区分缓存。

#### `patch_cache_control(response, **kwargs)`

这个函数通过添加所有关键字参数来修补 `Cache-Control` 头。变化如下：

- 所有的关键字参数名都转为小写，下划线转为连字符。
- 如果一个参数的值是 `True` （确切地说是 `True`，而不仅仅是一个真值），那么只有参数名称会被添加到头。
- 所有其他参数在应用 `str()` 后，都会加上其值。

#### `get_max_age(response)`

以整数形式返回响应 Cache-Control 头的最大寿命（如果没有找到或不是整数，则返回 `None`）。

#### `patch_response_headers(response, cache_timeout=None)`

为给定的 `HttpResponse` 对象添加一些有用的头信息。

- `Expires`
- `Cache-Control`

每个头只有在还没有设置的情况下才会被添加。

`cache_timeout` 的单位是秒。默认使用 [`CACHE_MIDDLEWARE_SECONDS`](/zh-hans/4.1/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS) 配置。

#### `add_never_cache_headers(response)`

Adds an `Expires` header to the current date/time.

在响应中添加 `Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private` 头，以表明页面永远不会被缓存。

每个头只有在还没有设置的情况下才会被添加。

#### `patch_vary_headers(response, newheaders)`

Adds (or updates) the `Vary` header in the given `HttpResponse` object.
`newheaders` is a list of header names that should be in `Vary`. If
headers contains an asterisk, then `Vary` header will consist of a single
asterisk `'*'`, according to [**RFC 7231 Section 7.1.4**](https://datatracker.ietf.org/doc/html/rfc7231.html#section-7.1.4). Otherwise,
existing headers in `Vary` aren't removed.

#### `get_cache_key(request, key_prefix=None, method='GET', cache=None)`

返回一个基于请求路径的缓存密钥。它可以在请求阶段使用，因为它从全局路径注册表中提取要考虑的头列表，并使用这些头建立一个缓存密钥来进行检查。

如果没有存储头列表，则需要重建页面，因此该函数返回 `None`。

#### `learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None)`

从响应对象中学习某些请求路径要考虑的头信息。它将这些头存储在全局路径注册表中，这样以后访问该路径时就可以知道要考虑哪些头，而无需建立响应对象本身。头在响应的 `Vary` 头中命名，但我们要防止响应生成。

用于生成缓存密钥的头列表和页面本身一样存储在缓存中。如果缓存将一些数据从缓存中过期，这意味着我们必须构建一次响应，以获得 Vary 头，因此也就获得了用于缓存密钥的头列表。

## `django.utils.dateparse`

本模块中定义的函数共享以下属性：

- 它们接受 ISO 8601 日期／时间格式的字符串（或一些接近的替代格式），并从 Python 的 [`datetime`](https://docs.python.org/3/library/datetime.html#module-datetime) 模块的相应类中返回对象。
- 如果他们的输入格式很好，但不是有效的日期或时间，他们会引发 [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)。
- 如果输入格式不好，则返回 `None`。
- 它们接受最多皮秒精度的输入，但它们将其截断为微秒，因为这是 Python 支持的。

#### `parse_date(value)`

解析一个字符串并返回一个 [`datetime.date`](https://docs.python.org/3/library/datetime.html#datetime.date)。

#### `parse_time(value)`

解析一个字符串并返回一个 [`datetime.time`](https://docs.python.org/3/library/datetime.html#datetime.time)。

不支持 UTC 偏移；如果 `value` 描述的是 UTC 偏移，结果是 `None`。

#### `parse_datetime(value)`

解析一个字符串并返回一个 [`datetime.datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)。

支持 UTC 偏移；如果 `value` 描述的是 UTC 偏移，则结果的 `tzinfo` 属性是一个 [`datetime.timezone`](https://docs.python.org/3/library/datetime.html#datetime.timezone) 实例。

#### `parse_duration(value)`

解析一个字符串并返回一个 [`datetime.timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta)。

要求数据格式为 `"DD HH:MM:SS.uuuuu"`、`"DD HH:MM:SS,uuuuu"` 或 ISO 8601 规定的格式（例如 `P4DT1H15M20S` 相当于 `4 1:15:20`）或 PostgreSQL 的日期时间间隔格式（例如 `3 days 04:05:06`）。

## `django.utils.decorators`

#### `method_decorator(decorator, name='')`

将函数装饰器转换为方法装饰器。它可以用来装饰方法或类；在后一种情况下，`name` 是要装饰的方法的名称，并且是必需的。

`decorator` 也可以是一个函数列表或元组。它们以相反的顺序包装，因此调用顺序是函数在列表／元组中出现的顺序。

参见 [装饰基于类的视图](/zh-hans/4.1/topics/class-based-views/intro/#id1) 的用法示例。

#### `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()`](/zh-hans/4.1/topics/cache/#django.views.decorators.cache.cache_page) 装饰器是从 `CacheMiddleware` 中创建的，就像这样：

```
cache_page = decorator_from_middleware_with_args(CacheMiddleware)

@cache_page(3600)
def my_view(request):
    pass
```

#### `sync_only_middleware(middleware)`

将一个中间件标记为 [仅同步](/zh-hans/4.1/topics/http/middleware/#async-middleware)。（Django 中的默认值，但这允许你在未来的版本中改变默认值的情况下对其进行保护。）

#### `async_only_middleware(middleware)`

将一个中间件标记为 [仅异步](/zh-hans/4.1/topics/http/middleware/#async-middleware)。当它从 WSGI 请求路径被调用时，Django 将把它包装在异步事件循环中。

#### `sync_and_async_middleware(middleware)`

将中间件标记为 [同步和异步兼容](/zh-hans/4.1/topics/http/middleware/#async-middleware)，这样可以避免转换请求。你必须实现对当前请求类型的检测才能使用这个装饰器。详情请看 [异步中间件文档](/zh-hans/4.1/topics/http/middleware/#async-middleware)。

## `django.utils.encoding`

#### `smart_str(s, encoding='utf-8', strings_only=False, errors='strict')`

返回一个代表任意对象 `s` 的 `str` 对象。使用 `encoding` 编解码器处理字节字符串。

如果 `strings_only` 是 `True`，不要转换（一些）非字符串类对象。

#### `is_protected_type(obj)`

确定对象实例是否属于一个受保护的类型。

当传递给 `force_str(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 Section 3.1**](https://datatracker.ietf.org/doc/html/rfc3987.html#section-3.1) 中第 3.1 节的算法，由于假设输入是一个字符串而不是任意字节流，所以略作简化。

取一个 IRI（字符串或 UTF-8 字节）并返回一个包含编码结果的字符串。

#### `uri_to_iri(uri)`

将统一资源标识符转换为国际化资源标识符。

这是 [**RFC 3987 Section 3.2**](https://datatracker.ietf.org/doc/html/rfc3987.html#section-3.2) 第 3.2 节中的一个算法。

获取一个 ASCII 字节的 URI，并返回一个包含编码结果的字符串。

#### `filepath_to_uri(path)`

将一个文件系统路径转换为适合包含在 URL 中的 URI 部分。路径假定为 UTF-8 字节、字符串或一个 [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)。

本方法将对某些通常被识别为 URI 特殊字符的字符进行编码。 请注意，本方法不对 ' 字符进行编码，因为它是 URI 中的有效字符。更多细节请参见 `encodeURIComponent()` JavaScript 函数。

返回一个包含编码结果的 ASCII 字符串。

#### `escape_uri_path(path)`

从统一资源标识符（URI）的路径部分转出不安全字符。

## `django.utils.feedgenerator`

示例用法：

```
>>> from django.utils import feedgenerator
>>> feed = feedgenerator.Rss201rev2Feed(
...     title="Poynter E-Media Tidbits",
...     link="http://www.poynter.org/column.asp?id=31",
...     description="A group blog by the sharpest minds in online media/journalism/publishing.",
...     language="en",
... )
>>> feed.add_item(
...     title="Hello",
...     link="http://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>

### `SyndicationFeed`

#### `class SyndicationFeed`

Base class for all syndication feeds. Subclasses should provide
`write()`.

#### `__init__(title, link, description, language=None, author_email=None, author_name=None, author_link=None, subtitle=None, categories=None, feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs)`

用给定的元数据字典初始化 feed，它适用于整个 feed。

你传递给 `__init__` 的任何额外的关键字参数将被存储在 `self.feed` 中。

所有参数都应该是字符串，但 `categories` 除外，它应该是一个字符串序列。

#### `add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs)`

添加一个项目到 feed 中。除了 `pubdate` 和 `updateddate` 是 `datetime.datetime` 对象和 `enclosures` 是 `Enclosure` 实例的列表外，所有参数都应该是字符串。

#### `num_items()`

#### `root_attributes()`

返回要放在根元素（即 feed/channel）上的额外属性。从 `write()` 调用。

#### `add_root_elements(handler)`

在根（即 feed/channel）元素中添加元素。由 `write()` 调用。

#### `item_attributes(item)`

返回要放在每个项目（即 item/entry）元素上的额外属性。

#### `add_item_elements(handler, item)`

在每个项目（即 item/entry）元素上添加元素。

#### `write(outfile, encoding)`

将给定编码的 feed 输出到 `outfile`，这是一个类似文件的对象。子类应该覆盖这个。

#### `writeString(encoding)`

以字符串形式返回给定编码的 feed。

#### `latest_post_date()`

返回 feed 中所有项目的最新 `pubdate` 或 `updateddate`。如果没有项目有这些属性，则返回当前的 UTC 日期／时间。

### `Enclosure`

#### `class Enclosure`

代表一个 RSS enclosure

### `RssFeed`

#### `class RssFeed(SyndicationFeed)`

### `Rss201rev2Feed`

#### `class Rss201rev2Feed(RssFeed)`

参见： <https://cyber.harvard.edu/rss/rss.html>

### `RssUserland091Feed`

#### `class RssUserland091Feed(RssFeed)`

参见： <http://backend.userland.com/rss091>

### `Atom1Feed`

#### `class Atom1Feed(SyndicationFeed)`

规格： [**RFC 4287**](https://datatracker.ietf.org/doc/html/rfc4287.html)

## `django.utils.functional`

#### `class cached_property(func, name=None)`

`@cached_property` 装饰器将一个方法的结果缓存起来，该方法有一个 `self` 参数作为属性。只要实例存在，缓存的结果就会持续存在，所以如果实例被传来传去，并且随后函数被调用，缓存的结果就会被返回。

考虑一个典型的情况，在将模型实例放入上下文之前，视图可能需要调用模型的方法来执行一些计算，在上下文中，模板可能会再次调用该方法：

```
# the model
class Person(models.Model):

    def friends(self):
        # expensive computation
        ...
        return friends

# in the view:
if person.friends():
    ...
```

而在模板中，你会有：

```html+django
{% 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"]
```

由于 [描述符协议](https://docs.python.org/3/reference/datamodel.html#descriptor-invocation) 的工作方式，在一个没有被访问过的 `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
```

> **Deprecated since Django 4.1**
>
> Deprecated since version 4.1: The `name` parameter is deprecated and will be removed in Django 5.0
> as it's unnecessary as of Python 3.6.

#### `class classproperty(method=None)`

与 [`@classmethod`](https://docs.python.org/3/library/functions.html#classmethod) 类似，`@classproperty` 装饰器将带有单个 `cls` 参数的方法的结果转换为可以直接从类中访问的属性。

#### `keep_lazy(func, *resultclasses)`

Django 提供了许多实用函数（特别是在 `django.utils` 中），这些函数将一个字符串作为它们的第一个参数，并对该字符串进行处理。这些函数可以被模板过滤器使用，也可以直接在其他代码中使用。

如果你自己编写类似的函数并处理翻译，你会面临这样一个问题：当第一个参数是一个惰性翻译对象时，该怎么办？你不想立即将其转换为字符串，因为你可能会在视图之外使用这个函数（因此当前线程的 locale 配置将不正确）。

对于这样的情况，可以使用 `django.utils.functional.keep_lazy()` 装饰器。它可以修改函数，使其在调用时，*如果* 参数是惰性翻译，则函数的执行会被延迟，直到需要将其转换为字符串。

例子：

```
from django.utils.functional import keep_lazy, keep_lazy_text

def fancy_utility_function(s, ...):
    # 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, ...):
    ...
```

`keep_lazy()` 装饰器需要一些额外的参数（`*args`）来指定原始函数可以返回的类型。一个常见的用例是返回文本的函数。对于这些函数，你可以将 `str` 类型传递给 `keep_lazy` （或者使用下一节描述的 [`keep_lazy_text()`](#django.utils.functional.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, ...):
    ...

# Which can be rewritten as:
@keep_lazy_text
def fancy_utility_function(s, ...):
    ...
```

## `django.utils.html`

通常情况下，你应该使用 Django 的模板来构建 HTML，以利用它的自动转义机制，在适当的地方使用 [`django.utils.safestring`](#module-django.utils.safestring) 中的实用程序。这个模块提供了一些额外的低级实用程序来处理 HTML。

#### `escape(text)`

返回给定的文本，并对其的符号、引号和角括号进行编码，以便在 HTML 中使用。输入的内容首先被强制为一个字符串，输出的内容被应用了 [`mark_safe()`](#django.utils.safestring.mark_safe)。

#### `conditional_escape(text)`

Similar to `escape()`, except that it doesn't operate on preescaped
strings, so it will not double escape.

#### `format_html(format_string, *args, **kwargs)`

这与 [`str.format()`](https://docs.python.org/3/library/stdtypes.html#str.format) 类似，只是它适合于构建 HTML 片段。所有的 args 和 kwargs 在传递给 `str.format()` 之前都要经过 [`conditional_escape()`](#django.utils.html.conditional_escape)。

对于构建小型 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()`](#django.utils.html.escape)，如果你忘记了一个参数，就有可能出现错误和 XSS 漏洞。

请注意，虽然这个函数使用 `str.format()` 来进行内插，但 `str.format()` 提供的一些格式化选项（例如数字格式化）将无法使用，因为所有参数都通过 [`conditional_escape()`](#django.utils.html.conditional_escape)，而这个函数（最终）会调用 [`force_str()`](#django.utils.encoding.force_str) 来处理这些值。

#### `format_html_join(sep, format_string, args_generator)`

[`format_html()`](#django.utils.html.format_html) 的一个封装器，用于常见的情况，即一组参数需要使用相同的格式字符串进行格式化，然后使用 `sep` 加入。`sep` 也通过 [`conditional_escape()`](#django.utils.html.conditional_escape) 传递。

`args_generator` 应该是一个迭代器，返回 `args` 的序列，这些序列将传递给 [`format_html()`](#django.utils.html.format_html)。例如：

```
format_html_join(
    '\n', "<li>{} {}</li>",
    ((u.first_name, u.last_name) for u in users)
)
```

#### `json_script(value, element_id=None)`

Escapes all HTML/XML special characters with their Unicode escapes, so
value is safe for use with JavaScript. Also wraps the escaped JSON in a
`<script>` tag. If the `element_id` parameter is not `None`, the
`<script>` tag is given the passed id. For example:

```
>> json_script({"hello": "world"}, element_id="hello-data")
'<script id="hello-data" type="application/json">{"hello": "world"}</script>'
```

> **Changed in Django 4.1**
>
> In older versions, the `element_id` argument was required.

#### `strip_tags(value)`

试图从字符串中删除任何类似 HTML 标签的内容，即包含在 `<>` 内的任何内容。

绝对不能保证结果的字符串是 HTML 安全的。所以千万不要在没有转义的情况下将 `strip_tag` 调用的结果标记为安全，例如使用 [`escape()`](#django.utils.html.escape)。

例子：

```
strip_tags(value)
```

如果 `value` 是 `"<b>Joel</b> <button>is</button> a <span>slug</span>"` 返回值将是 `"Joel is a slug"`。

如果你正在寻找一个更强大的解决方案，可以看看 [bleach](https://pypi.org/project/bleach/) Python 库。

#### `html_safe()`

类上的 `__html__()` 方法可以帮助非 Django 模板检测其输出不需要 HTML 转义的类。

这个装饰器通过在 [`mark_safe()`](#django.utils.safestring.mark_safe) 中封装 `__str__()` 来定义被装饰的类上的 `__html__()` 方法。确保 `__str__()` 方法确实返回不需要 HTML 转义的文本。

## `django.utils.http`

#### `urlencode(query, doseq=False)`

Python 的 [`urllib.parse.urlencode()`](https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlencode) 函数的一个版本，可以对 `MultiValueDict` 和非字符串值进行操作。

#### `http_date(epoch_seconds=None)`

将时间格式化为与 HTTP [**RFC 1123 Section 5.2.14**](https://datatracker.ietf.org/doc/html/rfc1123.html#section-5.2.14) 指定的日期格式相匹配的 [**RFC 7231 Section 7.1.1.1**](https://datatracker.ietf.org/doc/html/rfc7231.html#section-7.1.1.1)。

接受自 UTC 以来以秒为单位的浮点数，如 `time.time()` 输出的时间。如果设置为 `None`，默认为当前时间。

输出格式为 `Wdy, DD Mon YYYY HH:MM:SS GMT` 的字符串。

#### `base36_to_int(s)`

将 base 36 的字符串转换为整数。

#### `int_to_base36(i)`

将一个正整数转换为 base 36 字符串。

#### `urlsafe_base64_encode(s)`

将一个字节字符串编码为 base64 字符串，用于 URL 中，去掉所有尾部的等号。

#### `urlsafe_base64_decode(s)`

解码一个 base64 编码的字符串，将可能被剥离的尾部等号加回来。

## `django.utils.module_loading`

用于处理 Python 模块的函数。

#### `import_string(dotted_path)`

导入一个点分隔模块路径，并返回路径中最后一个名字所指定的属性／类。如果导入失败，则引发 `ImportError`。例如：

```
from django.utils.module_loading import import_string
ValidationError = import_string('django.core.exceptions.ValidationError')
```

相当于：

```
from django.core.exceptions import ValidationError
```

## `django.utils.safestring`

用于处理 “安全字符串” 的函数和类：在 HTML 中无需进一步转义就可以安全显示的字符串。将某一字符串标记为 “安全字符串” 意味着该字符串的制作者已经将那些不应该被 HTML 引擎解释的字符（例如 '\<'）转化为适当的实体。

#### `class SafeString`

`str` 子类，为了 HTML 输出的目的，被特别标记为 “安全”（不需要进一步的转义）。

#### `mark_safe(s)`

为（HTML）输出目的明确标记一个字符串为安全的。返回的对象可以用在任何适合字符串的地方。

可以在一个字符串上多次调用。

也可作为装饰器使用。

对于构建 HTML 片段，你通常应该使用 [`django.utils.html.format_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)`

一个 [`str.format()`](https://docs.python.org/3/library/stdtypes.html#str.format) 用于 `format_string`、args\` 和／或 `kwargs` 包含惰性对象时的版本。第一个参数是要格式化的字符串。例如：

```
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。

1. 如果 `allow_unicode` 为 `False` （默认），则转换为 ASCII 码。
2. 转换为小写。
3. 删除非字母数字、下划线、连字符或空格的字符。
4. 将任何空格或重复的破折号替换为单破折号。
5. Removing leading and trailing whitespace, dashes, and underscores.

例子：

```
>>> slugify(' Joel is a slug ')
'joel-is-a-slug'
```

如果你想允许使用 Unicode 字符，请传递 `allow_unicode=True`。例如：

```
>>> slugify('你好 World', allow_unicode=True)
'你好-world'
```

## `django.utils.timezone`

#### `utc`

[`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.tzinfo) 实例，表示 UTC。

> **Deprecated since Django 4.1**
>
> Deprecated since version 4.1: This is an alias to [`datetime.timezone.utc`](https://docs.python.org/3/library/datetime.html#datetime.timezone.utc). Use
> [`datetime.timezone.utc`](https://docs.python.org/3/library/datetime.html#datetime.timezone.utc) directly.

#### `get_fixed_timezone(offset)`

返回一个 [`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.tzinfo) 实例，该实例表示一个与 UTC 有固定偏移的时区。

`offset` 是一个 [`datetime.timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta) 或一个整数分钟。UTC 以东的时区为正值，UTC 以西的时区为负值。

#### `get_default_timezone()`

返回一个 [`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.tzinfo) 实例，表示 [默认时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

#### `get_default_timezone_name()`

返回 [默认时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone) 的名称。

#### `get_current_timezone()`

返回一个 [`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.tzinfo) 实例，表示 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

#### `get_current_timezone_name()`

返回 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone) 的名称。

#### `activate(timezone)`

设置 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。`timezone` 参数必须是 [`tzinfo`](https://docs.python.org/3/library/datetime.html#datetime.tzinfo) 子类的实例或时区名称。

#### `deactivate()`

取消设置 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

#### `override(timezone)`

这是一个 Python 上下文管理器，它在进入时通过 [`activate()`](#django.utils.timezone.activate) 设置 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)，并在退出时恢复之前的活动时区。如果 `timezone` 参数是 `None`，则 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone) 在进入时用 [`deactivate()`](#django.utils.timezone.deactivate) 取消设置。

`override` 也可作为函数装饰器使用。

#### `localtime(value=None, timezone=None)`

将一个感知的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) 转换为不同的时区，默认为 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

当省略 `value` 时，默认为 [`now()`](#django.utils.timezone.now)。

这个函数不适用于 naive 的日期，请使用 [`make_aware()`](#django.utils.timezone.make_aware) 代替。

#### `localdate(value=None, timezone=None)`

使用 [`localtime()`](#django.utils.timezone.localtime) 将一个已知道的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime) 转换为不同时区的 [`date()`](https://docs.python.org/3/library/datetime.html#datetime.datetime.date)，默认为 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

当省略 `value` 时，默认为 [`now()`](#django.utils.timezone.now)。

此功能不适用于 naive 的日期。

#### `now()`

返回一个 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)，表示当前的时间点。具体返回什么取决于 [`USE_TZ`](/zh-hans/4.1/ref/settings/#std-setting-USE_TZ) 的值。

- 如果 [`USE_TZ`](/zh-hans/4.1/ref/settings/#std-setting-USE_TZ) 是 `False`，这将是一个 [naive](/zh-hans/4.1/topics/i18n/timezones/#naive-vs-aware-datetimes) 的日期时间（即一个没有关联时区的日期时间），代表系统当地时区的当前时间。
- 如果 [`USE_TZ`](/zh-hans/4.1/ref/settings/#std-setting-USE_TZ) 是 `True`，这将是一个 [aware](/zh-hans/4.1/topics/i18n/timezones/#naive-vs-aware-datetimes) 的日期时间，代表当前的 UTC 时间。请注意，无论 [`TIME_ZONE`](/zh-hans/4.1/ref/settings/#std-setting-TIME_ZONE) 的值是多少， [`now()`](#django.utils.timezone.now) 将始终返回以 UTC 为单位的时间；你可以使用 [`localtime()`](#django.utils.timezone.localtime) 来获取当前时区的时间。

#### `is_aware(value)`

如果 `value` 是感知的，返回 `True`，如果是 naive 的，则返回 `False`。本函数假设 `value` 是一个 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)。

#### `is_naive(value)`

如果 `value` 是 naive 的，返回 `True`，如果是感知的，则返回 `False`。本函数假设 `value` 是一个 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)。

#### `make_aware(value, timezone=None, is_dst=None)`

返回一个感知的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)，在 `timezone` 中表示与 `value` 相同的时间点，`value` 是一个 naive 的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)。如果 `timezone` 设置为 `None`，则默认为 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

> **Deprecated since Django 4.0**
>
> Deprecated since version 4.0: When using `pytz`, the `pytz.AmbiguousTimeError` exception is
> raised if you try to make `value` aware during a DST transition where
> the same time occurs twice (when reverting from DST). Setting
> `is_dst` to `True` or `False` will avoid the exception by
> choosing if the time is pre-transition or post-transition respectively.
>
> When using `pytz`, the `pytz.NonExistentTimeError` exception is
> raised if you try to make `value` aware during a DST transition such
> that the time never occurred. For example, if the 2:00 hour is skipped
> during a DST transition, trying to make 2:30 aware in that time zone
> will raise an exception. To avoid that you can use `is_dst` to
> specify how `make_aware()` should interpret such a nonexistent time.
> If `is_dst=True` then the above time would be interpreted as 2:30 DST
> time (equivalent to 1:30 local time). Conversely, if `is_dst=False`
> the time would be interpreted as 2:30 standard time (equivalent to 3:30
> local time).
>
> The `is_dst` parameter has no effect when using non-`pytz` timezone
> implementations.
>
> `is_dst` 参数已被废弃，将在 Django 5.0 中删除。

#### `make_naive(value, timezone=None)`

返回一个 naive 的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)，它在 `timezone` 中表示与 `value` 相同的时间点，`value` 是一个感知的 [`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)。如果 `timezone` 设置为 `None`，则默认为 [当前时区](/zh-hans/4.1/topics/i18n/timezones/#default-current-time-zone)。

## `django.utils.translation`

关于以下用法的完整讨论，请参见 [翻译文档](/zh-hans/4.1/topics/i18n/translation/)。

#### `gettext(message)`

翻译 `message` 并以字符串形式返回。

#### `pgettext(context, message)`

翻译 `message` 给定的 `context` 并以字符串形式返回。

更多信息，见 [上下文标记](/zh-hans/4.1/topics/i18n/translation/#contextual-markers)。

#### `gettext_lazy(message)`

#### `pgettext_lazy(context, message)`

和上面的非惰性版本一样，但使用惰性执行。

参见 [惰性翻译文档](/zh-hans/4.1/topics/i18n/translation/#lazy-translations)。

#### `gettext_noop(message)`

标记要翻译的字符串，但现在不翻译它们。这可以用来存储全局变量中的字符串，这些字符串应该留在基础语言中（因为它们可能会被外部使用），并在以后被翻译。

#### `ngettext(singular, plural, number)`

翻译 `singular` 和 `plural`，并根据 `number` 返回相应的字符串。

#### `npgettext(context, singular, plural, number)`

翻译 `singular` 和 `plural`，并根据 `number` 和 `context` 返回适当的字符串。

#### `ngettext_lazy(singular, plural, number)`

#### `npgettext_lazy(context, singular, plural, number)`

和上面的非惰性版本一样，但使用惰性执行。

参见 [惰性翻译文档](/zh-hans/4.1/topics/i18n/translation/#lazy-translations)。

#### `activate(language)`

获取给定语言的翻译对象，并将其激活为当前线程的当前翻译对象。

#### `deactivate()`

停用当前活动的翻译对象，以便进一步的 \_ 调用将再次针对默认翻译对象进行解析。

#### `deactivate_all()`

使活动翻译对象成为 `NullTranslations()` 实例。当我们出于某种原因想让延迟翻译以原始字符串的形式出现时，这很有用。

#### `override(language, deactivate=False)`

一个 Python 上下文管理器，它使用 [`django.utils.translation.activate()`](#django.utils.translation.activate) 获取给定语言的翻译对象，将其激活为当前线程的翻译对象，并在退出时重新激活之前的活动语言。如果 `deactivate` 参数为 `True`，则可以用 [`django.utils.translation.deactivate()`](#django.utils.translation.deactivate) 在退出时停用临时翻译对象。如果传递 `None` 作为语言参数，则会在上下文中激活 `NullTranslations()` 实例。

`override` 也可作为函数装饰器使用。

#### `check_for_language(lang_code)`

检查是否有给定语言代码的全局语言文件（如 'fr'、'pt\_BR'）。这用于决定用户提供的语言是否可用。

#### `get_language()`

返回当前选择的语言代码。如果翻译被暂时停用（通过 [`deactivate_all()`](#django.utils.translation.deactivate_all) 或当 `None` 被传递给 [`override()`](#django.utils.translation.override) 时），返回 `None`。

#### `get_language_bidi()`

返回所选语言的 BiDi 布局。

- `False` = 从左到右布局
- `True` = 从右到左布局

#### `get_language_from_request(request, check_path=False)`

分析请求，找出用户希望系统显示的语言。只考虑 settings.LANGUAGES 中列出的语言。如果用户请求的是我们有主语言的子语言，我们会发送主语言。

如果 `check_path` 为 `True`，则函数首先检查请求的 URL 的路径是否以 [`LANGUAGES`](/zh-hans/4.1/ref/settings/#std-setting-LANGUAGES) 配置中列出的语言代码开头。

#### `get_supported_language_variant(lang_code, strict=False)`

如果在 [`LANGUAGES`](/zh-hans/4.1/ref/settings/#std-setting-LANGUAGES) 配置中，则返回 `lang_code`，可能会选择一个更通用的变量。例如，如果 `lang_code` 是 `'es-ar'`，并且 `'es'` 在 [`LANGUAGES`](/zh-hans/4.1/ref/settings/#std-setting-LANGUAGES) 中，但 `'es-ar'` 没有，则返回 `'es'`。

如果 `strict` 是 `False` （默认），当语言代码和通用变体都没有找到时，可能会返回一个特定国家的变体。例如，如果 [`LANGUAGES`](/zh-hans/4.1/ref/settings/#std-setting-LANGUAGES) 中只有 `'es-co'`，那么就会返回 `lang_code`，如 `'es'` 和 `'es-ar'`。如果 `strict=True`，则不会返回这些匹配。

如果没有找到任何东西，会引发 [`LookupError`](https://docs.python.org/3/library/exceptions.html#LookupError)。

#### `to_locale(language)`

将语言名称（en-us）转换为 locale 名称（en\_US）。

#### `templatize(src)`

将 Django 模板转化为能被 `xgettext` 理解的东西。它通过将 Django 翻译标签翻译成标准的 `gettext` 函数调用来实现。
