# Django 5.2.8 documentation

# Django 4.0 版本发行说明

2021 年 12 月 7 日

欢迎使用 Django 4.0 ！

这些发布说明涵盖了 新功能，以及从 Django 3.2 或更早版本升级时需要注意的一些 不向后兼容的变更。我们已经 开始了一些功能的弃用过程。

如果你要更新现有的项目，请看 如何将 Django 更新至新的版本 指南。

## Python 兼容性

Django 4.0 支持 Python 3.8、3.9 和 3.10。我们 强烈建议 并只官方支持每个系列的最新版本。

Django 3.2.x 系列是最后一个支持 Python 3.6 和 3.7 的版本。

## Django 4.0 新特性

### `zoneinfo` 默认时区实现

Python 标准库的 `zoneinfo` 现在是 Django 中默认的时区实现。

这是从使用 `pytz` 到使用 `zoneinfo` 迁移的下一步。Django 3.2 允许使用非 `pytz` 时区。Django 4.0 将 `zoneinfo` 作为默认实现。对于 `pytz` 的支持现在已经不推荐使用，并将在 Django 5.0 中移除。

`zoneinfo` 是自 Python 3.9 起的 Python 标准库的一部分。如果你正在使用 Python 3.8，那么 `backports.zoneinfo` 包会在安装 Django 时自动安装。

迁移到 `zoneinfo` 应该在很大程度上是透明的。选择当前时区、在表单和模板中将日期时间实例转换为当前时区，以及在 UTC 中进行的带时区日期时间的操作都不受影响。

然而，如果你正在使用非 UTC 时区，并使用 `pytz` 的 `normalize()` 和 `localize()` API，可能还涉及到 `TIME_ZONE` 设置，那么你需要审查你的代码，因为``pytz`` 和 `zoneinfo` 并不完全等同。

为了给这样的审核留出时间，过渡性的 `USE_DEPRECATED_PYTZ` 设置允许在 4.x 发布周期内继续使用 `pytz`。这个设置将在 Django 5.0 中移除。

此外，`zoneinfo` 的作者创建了一个名为 pytz_deprecation_shim 的包，可用于协助从 `pytz` 迁移。这个包提供了帮助你安全移除 `pytz` 的 shims，并有一个详细的 迁移指南，展示了如何切换到新的 `zoneinfo` API。

如果需要逐步更新路径，建议使用 pytz_deprecation_shim 和过渡性的 `USE_DEPRECATED_PYTZ` 设置。

### 函数式唯一约束

`UniqueConstraint()` 的新的 `*expressions` 位置参数允许在表达式和数据库函数上创建功能性的唯一约束。例如：

    from django.db import models
    from django.db.models import UniqueConstraint
    from django.db.models.functions import Lower

    class MyModel(models.Model):
        first_name = models.CharField(max_length=255)
        last_name = models.CharField(max_length=255)

        class Meta:
            constraints = [
                UniqueConstraint(
                    Lower("first_name"),
                    Lower("last_name").desc(),
                    name="first_last_name_unique",
                ),
            ]

功能性唯一约束是通过在模型中使用 `Meta.constraints` 选项来添加的。

### `scrypt` 密码哈希器

新的 scrypt 密码哈希器 更安全，推荐使用，但它不是默认选项，因为它需要 OpenSSL 1.1+ 和更多内存。

### Redis 缓存后端

新的 `django.core.cache.backends.redis.RedisCache` 缓存后端提供了内置的支持，用于使用 Redis 进行缓存。需要 redis-py 的版本为 3.0.0 或更高。更多详情请参阅 Django 中关于使用 Redis 进行缓存的 文档。

### 基于模板的表单渲染

`Forms`、Formsets 和 `ErrorList` 现在使用模板引擎进行渲染，以增强自定义功能。查看 `Form` 的新方法 `render()`、`get_context()` 和 `template_name`，以及关于 `Formset` 的 formset 渲染。

### 次要特性

#### `django.contrib.admin`

- `admin/base.html` 模板现在有一个新的块 `header`，其中包含了管理站点的标题。

- 新的 `ModelAdmin.get_formset_kwargs()` 方法允许自定义传递给表单集构造函数的关键字参数。

- 导航侧边栏现在有一个快速筛选工具栏。

- 新的上下文变量 `model` 包含了每个模型的模型类，已添加到 `AdminSite.each_context()` 方法中。

- 新的 `ModelAdmin.search_help_text` 属性允许指定搜索框的描述性文本。

- `InlineModelAdmin.verbose_name_plural` 属性现在会回退到 `InlineModelAdmin.verbose_name` + `'s'`。

- jQuery 从版本 3.5.1 升级到 3.6.0 。

#### `django.contrib.admindocs`

- admindocs 现在允许复杂的设置，其中 `ROOT_URLCONF` 不是一个字符串。

- `admindocs` 的模型部分现在显示缓存的属性。

#### `django.contrib.auth`

- PBKDF2 密码哈希器的默认迭代次数从 260 , 000 增加到 320 , 000 。

- 新的 `LoginView.next_page` 属性和 `get_default_redirect_url()` 方法允许自定义登录后的重定向。

#### `django.contrib.gis`

- 新增对 SpatiaLite 5 的支持。

- `GDALRaster` 现在允许在任何 GDAL 虚拟文件系统中创建栅格数据。

- 新的 `GISModelAdmin` 类允许自定义用于 `GeometryField` 的小部件，这是鼓励使用的，而不是不推荐使用的 `GeoModelAdmin` 和 `OSMGeoAdmin`。

#### `django.contrib.postgres`

- PostgreSQL 后端现在支持通过服务名称进行连接。更多详情请参阅 PostgreSQL 连接配置。

- 新的 `AddConstraintNotValid` 操作允许在 PostgreSQL 上创建检查约束，而无需验证所有现有行是否满足新约束。

- 新的 `ValidateConstraint` 操作允许验证在 PostgreSQL 上使用 `AddConstraintNotValid` 创建的检查约束。

- 新的 `ArraySubquery()` 表达式允许在 PostgreSQL 上使用子查询来构建值列表。

- 新的 `trigram_word_similar` 查找以及 `TrigramWordDistance()` 和 `TrigramWordSimilarity()` 表达式允许使用 trigram 单词相似度。

#### `django.contrib.staticfiles`

- `ManifestStaticFilesStorage` 现在会将 JavaScript 源映射引用的路径替换为它们的哈希版本。

- `ManifestFilesMixin` 和 `ManifestStaticFilesStorage` 的新参数 `manifest_storage` 允许自定义清单文件的存储。

#### 缓存

- `django.core.cache.backends.base.BaseCache` 的新异步 API 开始了使缓存后端支持异步的过程。新的异步方法都有 `a` 前缀的名称，例如 `aadd()`、`aget()`、`aset()`、`aget_or_set()` 或 `adelete_many()`。

  今后，`a` 前缀将用于一般方法的异步变体。

#### CSRF

- CSRF 保护现在会查看是否存在 `Origin` 标头。为了实现这一点，需要对 `CSRF_TRUSTED_ORIGINS` 设置进行 一些更改。

#### 表单

- `ModelChoiceField` 现在会在引发 `invalid_choice` 错误消息的 `ValidationError` 中的 `params` 参数中包含提供的值，这允许自定义错误消息使用 `%(value)s` 占位符。

- `BaseFormSet` 现在会在渲染非表单错误时添加一个额外的类 `nonform`，以帮助区分它们与特定于表单的错误。

- `BaseFormSet` 现在允许通过设置 `deletion_widget` 属性或覆盖 `get_deletion_widget()` 方法来自定义在通过 `can_delete` 删除表单时使用的小部件。

#### 国际化

- 添加了对马来语的支持和翻译。

#### 通用视图

- `DeleteView` 现在使用 `FormMixin`，允许你提供一个 `Form` 的子类，例如带有复选框的表单，来确认删除。此外，这还允许 `DeleteView` 与 `django.contrib.messages.views.SuccessMessageMixin` 配合使用。

  根据 `FormMixin`，对于 POST 请求的对象删除是在 `form_valid()` 中处理的。如果需要，应将 `delete()` 处理程序中的自定义删除逻辑移动到 `form_valid()` 或共享的辅助方法中。

#### 日志

- 现在，用于 SQL 调用的数据库的别名会作为额外的上下文与每条消息一起传递到 django.db.backends 记录器中。

#### 管理命令

- `runserver` 管理命令现在支持 `--skip-checks` 选项。

- 在 PostgreSQL 上，`dbshell` 现在支持指定密码文件。

- The `shell` command now respects `sys.__interactivehook__` at startup. This allows loading shell history between interactive sessions. As a consequence, `readline` is no longer loaded if running in isolated mode.

- 新的 `BaseCommand.suppressed_base_arguments` 属性允许在帮助输出中抑制不支持的默认命令选项。

- 新的 `startapp --exclude` 和 `startproject --exclude` 选项允许从模板中排除目录。

#### 模型

- 新的 `QuerySet.contains(obj)` 方法返回查询集是否包含给定对象。它尝试以最简单和最快的方式执行查询。

- `Round()` 数据库函数的新 `precision` 参数允许指定舍入后的小数位数。

- 使用 SQLite 3.35+ 时，`QuerySet.bulk_create()` 现在会为对象设置主键。

- `DurationField` 现在在 SQLite 上支持乘法和除法以及标量值。

- `QuerySet.bulk_update()` 现在会返回更新的对象数量。

- 新的 `Expression.empty_result_set_value` 属性允许在函数用于空结果集时指定要返回的值。

- The `skip_locked` argument of `QuerySet.select_for_update()` is now allowed on MariaDB 10.6+.

- `Lookup` 表达式现在可以在 `QuerySet` 的注释、聚合和直接筛选中使用。

- 内置聚合函数的新 default 参数允许指定当查询集（或分组）不包含条目时要返回的值，而不是返回 `None`。

#### 请求和响应

- `SecurityMiddleware` 现在会添加具有值 `'same-origin'` 的 Cross-Origin Opener Policy 头，以防止跨源弹出窗口共享相同的浏览上下文。你可以通过将 `SECURE_CROSS_ORIGIN_OPENER_POLICY` 设置为 `None` 来阻止添加此头部。

#### 信号

- The new `stdout` argument for `pre_migrate()` and `post_migrate()` signals allows redirecting output to a stream-like object. It should be preferred over `sys.stdout` and `print()` when emitting verbose output in order to allow proper capture when testing.

#### 模板

- 模板过滤器 `floatformat` 现在允许使用 `u` 后缀来强制禁用本地化。

#### 测试

- `django.test.utils.setup_databases()` 的新参数 `serialized_aliases` 决定了哪些 `DATABASES` 别名的测试数据库应该被序列化以允许使用 serialized_rollback 特性。

- `test --buffer` 选项现在支持并行测试。

- The new `logger` argument to `DiscoverRunner` allows a Python logger to be used for logging.

- 新的 `DiscoverRunner.log()` 方法提供了一种记录消息的方式，它使用 `DiscoverRunner.logger` 进行日志记录，如果未设置则打印到控制台。

- `DiscoverRunner` 现在可以使用 `test --shuffle` 选项以随机顺序执行测试。

- `test --parallel` 选项现在支持值 `auto`，以为每个处理器核心运行一个测试进程。

- `TestCase.captureOnCommitCallbacks()` 现在会捕获在执行 `transaction.on_commit()` 回调期间添加的新回调。

## 4.0 版本中不向后兼容的变更

### 数据库后端 API

本节介绍了第三方数据库后端可能需要的更改。

- `DatabaseOperations.year_lookup_bounds_for_date_field()` 和 `year_lookup_bounds_for_datetime_field()` 方法现在接受可选的 `iso_year` 参数，以支持 ISO-8601 周编号年份的范围。

- `DatabaseSchemaEditor._unique_sql()` 和 `_create_unique_sql()` 方法的第二个参数现在是 `fields`，而不再是 `columns`。

### `django.contrib.gis`

- 移除了对 PostGIS 2.3 的支持。

- 移除了对 GDAL 2.0 和 GEOS 3.5 的支持。

### 停止支持 PostgreSQL 9.6

PostgreSQL 9.6 的上游支持将在 2021 年 11 月结束。 Django 4.0 支持 PostgreSQL 10 及更高版本。

此外，`psycopg2` 的最低支持版本已从 2.5.4 提高到 2.8.4，因为 `psycopg2` 2.8.4 是第一个支持 Python 3.8 的版本。

### 停止支持 Oracle 12.2 和 18c

Oracle 12.2 的上游支持将于 2022 年 3 月结束，Oracle 18c 的上游支持将于 2021 年 6 月结束。 Django 3.2 将得到支持直至 2024 年 4 月。 Django 4.0 正式支持 Oracle 19c 。

### `CSRF_TRUSTED_ORIGINS` 变更

#### 格式变更

在 `CSRF_TRUSTED_ORIGINS` 设置中，值必须包括方案（例如，`'http://'` 或 `'https://'`），而不仅仅是主机名。

此外，以点开头的值现在必须在点之前加上一个星号。例如，将 `'.example.com'` 更改为 `'https://*.example.com'`。

系统检查会检测到任何所需的更改。

#### 现在可能需要配置它

由于 CSRF 保护现在参考 `Origin` 标头，如果你通过将 `CSRF_COOKIE_DOMAIN` （或者如果启用了 `CSRF_USE_SESSIONS`，则为 `SESSION_COOKIE_DOMAIN`）设置为以点开头的值以允许来自子域的请求，你可能需要设置 `CSRF_TRUSTED_ORIGINS`。

### `SecurityMiddleware` 不再设置 `X-XSS-Protection` 头

如果 `SECURE_BROWSER_XSS_FILTER` 设置为 `True`，则 `SecurityMiddleware` 不再设置 `X-XSS-Protection` 头。此设置已被移除。

大多数现代浏览器不再支持 `X-XSS-Protection` HTTP 头。你可以使用 Content-Security-Policy 来代替，但请不要允许 `'unsafe-inline'` 脚本。

如果您想要支持旧版浏览器并设置标头，请在自定义中间件中使用以下代码行：

    response.headers.setdefault("X-XSS-Protection", "1; mode=block")

### 迁移自动检测器的更改

迁移自动检测器现在使用模型状态而不是模型类。此外，对于 `ForeignKey` 和 `ManyToManyField` 字段的迁移操作不再指定未在字段初始化期间传递的属性。

作为副作用，在某些情况下，运行 `makemigrations` 可能会为 `ManyToManyField` 和 `ForeignKey` 字段生成无操作的 `AlterField` 操作。

### `DeleteView` 变更

`DeleteView` 现在使用 `FormMixin` 来处理 POST 请求。因此，任何在 `delete()` 处理程序中的自定义删除逻辑应该移动到 `form_valid()`，或者如果需要的话，可以移动到共享的辅助方法。

### Oracle 上的表和列命名方案发生了变化。

Django 4.0 无意中更改了 Oracle 上的表和列命名方案。这会导致模型和字段的名称超过 30 个字符的错误。不幸的是，需要重命名一些 Oracle 表和列。请使用 33789 中的升级脚本生成 `RENAME` 语句来更改命名方案。

### 杂项

- 已移除对 `cx_Oracle` 版本低于 7.0 的支持。

- 为了允许在子路径上提供 Django 站点而不更改 `STATIC_URL` 的值，现在在默认的 `startproject` 模板中从该设置中移除了前导斜杠（现在是 `'static/'`）。

- 当直接访问 `AdminSite` 的管理 `index` 视图时，不再使用 `never_cache` 进行装饰，而是建议通过 `AdminSite.urls` 属性或 `AdminSite.get_urls()` 方法访问。

- 对切片的查询集执行不支持的操作现在会引发 `TypeError` 而不是 `AssertionError`。

- 未记录的 `django.test.runner.reorder_suite()` 函数已更名为 `reorder_tests()`。现在它接受一个测试的可迭代对象而不是测试套件，并返回一个测试的迭代器。

- 现在，如果使用空的 `name` 调用 `FileSystemStorage.delete()`，会引发 `ValueError` 而不是 `AssertionError`。

- 如果使用无效的 `content` 或 `mimetype` 参数调用 `EmailMultiAlternatives.attach_alternative()` 或 `EmailMessage.attach()`，现在会引发 `ValueError` 而不是 `AssertionError`。

- `assertHTMLEqual()` 不再将没有值的非布尔属性视为与具有相同名称和值的属性相等。

- 现在，无法加载的测试，例如由于语法错误等原因，使用 `test --tag` 时始终匹配。

- 未记录的 `django.contrib.admin.utils.lookup_needs_distinct()` 函数已更名为 `lookup_spawns_duplicates()`。

- 未记录的 `HttpRequest.get_raw_uri()` 方法已被移除。 `HttpRequest.build_absolute_uri()` 方法可能是一个合适的替代方法。

- 未记录的 `ModelAdmin.log_addition()`、`log_change()` 和 `log_deletion()` 方法的 `object` 参数已更名为 `obj`。

- `RssFeed`、`Atom1Feed` 及其子类现在将没有内容的元素作为自关闭标签进行输出。

- `NodeList.render()` 不再将单个节点的 `render()` 方法的输出转换为字符串。根据文档，`Node.render()` 应始终返回一个字符串。

- `django.db.models.sql.query.Query` 的 `where_class` 属性以及 `ForeignObject` 和 `ForeignObjectRel` 的私有方法 `get_extra_restriction()` 的 `where_class` 参数已被移除。如果需要，可以初始化 `django.db.models.sql.where.WhereNode`。

- 未记录的 `Query.add_filter()` 方法的 `filter_clause` 参数被替换为两个位置参数 `filter_lhs` 和 `filter_rhs`。

- `CsrfViewMiddleware` 现在使用 `request.META['CSRF_COOKIE_NEEDS_UPDATE']` 代替 `request.META['CSRF_COOKIE_USED']`、`request.csrf_cookie_needs_reset` 和 `response.csrf_cookie_set` 来跟踪 CSRF cookie 是否应该发送。这是一个未记录的私有 API。

- 未记录的 `TRANSLATOR_COMMENT_MARK` 常量已从 `django.template.base` 移动到 `django.utils.translation.template`。

- 未记录的 `django.db.migrations.state.ProjectState.__init__()` 方法的 `real_apps` 参数现在必须是一个集合（set），如果提供的话。

- `RadioSelect` 和 `CheckboxSelectMultiple` 小部件现在在 `<div>` 标签中呈现，以便屏幕阅读器更简洁地宣读它们。如果需要以前的行为，请使用来自 Django 3.2 的适当模板 覆盖小部件模板。

- 模板过滤器 `floatformat` 不再依赖于 `USE_L10N` 设置，并始终返回本地化的输出。使用 `u` 后缀来禁用本地化。

- `USE_L10N` 设置的默认值已更改为 `True`。有关更多详细信息，请参阅上面的 本地化部分。

- 作为 迁移到 zoneinfo 的一部分，`django.utils.timezone.utc` 被更改为别名 `datetime.timezone.utc`。

- `asgiref` 的最低支持版本已从 3.3.2 增加到 3.4.1。

## 在 4.0 版本中废弃的功能

### 使用 `pytz` 时区

作为 迁移到 zoneinfo 的一部分，不推荐使用 `pytz` 时区。

相应地，以下函数的 `is_dst` 参数也已被弃用：

- `django.db.models.query.QuerySet.datetimes()`

- `django.db.models.functions.Trunc()`

- `django.db.models.functions.TruncSecond()`

- `django.db.models.functions.TruncMinute()`

- `django.db.models.functions.TruncHour()`

- `django.db.models.functions.TruncDay()`

- `django.db.models.functions.TruncWeek()`

- `django.db.models.functions.TruncMonth()`

- `django.db.models.functions.TruncQuarter()`

- `django.db.models.functions.TruncYear()`

- `django.utils.timezone.make_aware()`

在 Django 5.0 中将移除对 `pytz` 的支持。

### 时区支持

为了遵循良好的实践，`USE_TZ` 设置的默认值将从 `False` 更改为 `True`，并且在 Django 5.0 中将默认启用时区支持。

请注意，由 `django-admin startproject` 创建的默认 `settings.py` 文件自 Django 1.4 起就包括 `USE_TZ = True`。

你可以在那之前在项目设置中将 `USE_TZ` 设置为 `False` 以选择不使用时区支持。

### 本地化

为了遵循良好的实践，`USE_L10N` 设置的默认值从 `False` 更改为 `True`。

此外，从此版本开始，`USE_L10N` 已被弃用。从 Django 5.0 开始，默认情况下，Django 显示的任何日期或数字都将进行本地化。

Django 仍将支持 `{% localize %}` 标签以及 `localize`/ `unlocalize` 过滤器。

### 杂项

- `SERIALIZE` 测试设置已被弃用，因为可以从启用 serialized_rollback 选项的 `databases` 推断出。

- 未记录的 `django.utils.baseconv` 模块已被弃用。

- 未记录的 `django.utils.datetime_safe` 模块已被弃用。

- 在 Django 5.0 中，构建在请求上下文之外的站点地图的默认协议将从 `'http'` 更改为 `'https'`。

- `DiscoverRunner.build_suite()` 和 `DiscoverRunner.run_tests()` 的 `extra_tests` 参数已被弃用。

- 在 Django 5.0 中，当没有行时，`ArrayAgg`、`JSONBAgg` 和 `StringAgg` 聚合将返回 `None`，而不是分别返回 `[]`、`[]` 和 `''`。如果需要以前的行为，请显式将 `default` 设置为 `Value([])`、`Value('[]')` 或 `Value('')`。

- `django.contrib.gis.admin.GeoModelAdmin` 和 `OSMGeoAdmin` 类已被弃用。请改为使用 `ModelAdmin` 和 `GISModelAdmin`。

- 由于表单渲染现在使用模板引擎，未记录的 `BaseForm._html_output()` 辅助方法已被弃用。

- 从 `ErrorList` 和 `ErrorDict` 返回 `str` 的能力已被弃用。预期这些方法返回一个 `SafeString`。

## 在 4.0 版本中移除的功能

这些功能已经完成了废弃周期，并在 Django 4.0 中被移除。

请参阅 在 3.0 中被废弃的功能 以获取有关这些更改的详细信息，包括如何删除对这些功能的使用。

- `django.utils.http.urlquote()`, `urlquote_plus()`, `urlunquote()`, 和 `urlunquote_plus()` 已被移除。

- `django.utils.encoding.force_text()` 和 `smart_text()` 已被移除。

- `django.utils.translation.ugettext()`, `ugettext_lazy()`, `ugettext_noop()`, `ungettext()`, 和 `ungettext_lazy()` 已被移除。

- `django.views.i18n.set_language()` 不会在 `request.session` 中设置用户语言（键为 `_language`）。

- `alias=None` 在 `django.db.models.Expression.get_group_by_cols()` 子类的签名中是必需的。

- `django.utils.text.unescape_entities()` 已被移除。

- `django.utils.http.is_safe_url()` 已被移除。

请参阅 在 3.1 中被废弃的功能 以获取有关这些更改的详细信息，包括如何删除对这些功能的使用。

- `PASSWORD_RESET_TIMEOUT_DAYS` 设置已被移除。

- `isnull` 查询不再允许使用非布尔值作为右侧的值。

- `django.db.models.query_utils.InvalidQuery` 异常类已被移除。

- `django-admin.py` 入口点已被移除。

- `HttpRequest.is_ajax()` 方法已被移除。

- 已移除对由 `django.contrib.messages.storage.cookie.CookieStorage` 使用的 Django 3.1 之前版本的 cookie 值编码格式的支持。

- 移除了对使用 SHA-1 哈希算法的 Django 3.1 之前版本密码重置令牌在管理站点的支持。

- 移除了对使用 Django 3.1 之前编码格式的会话的支持。

- 已移除对 Django 3.1 之前版本中使用 SHA-1 算法编码的 `django.core.signing.Signer` 签名的支持。

- 已移除在 `django.core.signing.loads()` 中对 Django 3.1 之前版本中使用 SHA-1 算法编码的 `django.core.signing.dumps()` 签名的支持。

- 移除了对使用 SHA-1 算法的 Django 3.1 之前用户会话的支持。

- `django.utils.deprecation.MiddlewareMixin.__init__()` 的 `get_response` 参数是必需的，并且不接受 `None`。

- `django.dispatch.Signal` 的 `providing_args` 参数已被移除。

- `django.utils.crypto.get_random_string()` 的 `length` 参数是必需的。

- `ModelMultipleChoiceField` 的 `list` 消息已被移除。

- 不再支持将原始列别名传递给 `QuerySet.order_by()`。

- `NullBooleanField` 模型字段已被移除，除了在历史迁移中的支持。

- `django.conf.urls.url()` 已被移除。

- `django.contrib.postgres.fields.JSONField` 模型字段已被移除，除了在历史迁移中的支持。

- `django.contrib.postgres.fields.jsonb.KeyTransform` 和 `django.contrib.postgres.fields.jsonb.KeyTextTransform` 已被移除。

- `django.contrib.postgres.forms.JSONField` 已被移除。

- `{% ifequal %}` 和 `{% ifnotequal %}` 模板标签已被移除。

- `DEFAULT_HASHING_ALGORITHM` 过渡设置已被移除。