---
title: "Django 3.1 版本发行说明"
version: 4.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/4.2/releases/3.1/
canonical: https://djangodocs.dev/zh-hans/4.2/releases/3.1/
---
# Django 3.1 版本发行说明

*2020 年 8 月 4 日*

欢迎来到 Django 3.1 版本！

此版本说明涵盖了一些 [新特性](#whats-new-3-1) ，以及从 Django 3.0 或更早版本升级时需要注意的 [向后不兼容](#backwards-incompatible-3-1) 的地方。我们已经 [删除了一些过期的功能](#removed-features-3-1) ，并且已经开始 [淘汰一些特性](#deprecated-features-3-1) 。

如果你要更新现有的项目，请看 [如何将 Django 更新至新的版本](/zh-hans/4.2/howto/upgrade-version/) 指南。

## Python 兼容性

Django 3.1 支持 Python 3.6、3.7、3.8 和 3.9（从 3.1.3 开始）。我们 **强烈推荐** 且官方只支持每个系列的最新版本。

## Django 3.1 新特性

### 异步视图和中间件支持

Django 现在支持完全异步的请求路径，包括：

- [异步视图](/zh-hans/4.2/topics/http/views/#async-views)
- [异步中间件](/zh-hans/4.2/topics/http/middleware/#async-middleware)
- [异步测试和测试客户端](/zh-hans/4.2/topics/testing/tools/#async-tests)

要开始使用异步视图，你需要使用 `async def` 来声明一个视图：

```
async def my_view(request):
    await asyncio.sleep(0.5)
    return HttpResponse("Hello, async world!")
```

无论你是在 WSGI 或 ASGI 模式下运行，都支持所有的异步功能。但是，在 WSGI 模式下使用 async 代码会有性能上的惩罚。你可以在 [异步支持](/zh-hans/4.2/topics/async/) 文档中阅读更多的具体内容。

你可以自由地混合异步和同步视图、中间件和测试，只要你愿意。Django 会确保你最终使用正确的执行上下文。我们希望大多数项目会保持大部分视图的同步，只有少数视图在异步模式下运行，但这完全是你的选择。

Django 的 ORM、缓存层和其他做长期网络调用的代码还不支持异步访问。我们希望在即将发布的版本中增加对它们的支持。但是，异步视图是很理想的，如果你在视图里面做了大量的 API 或 HTTP 调用，你现在可以原生地将所有这些 HTTP 调用并行进行，以大大加快你的视图的执行速度。

异步支持应该是完全向后兼容的，我们已经尝试确保它不会对你现有的同步代码造成速度上的倒退。它应该不会对任何现有的 Django 项目产生明显的影响。

### JSONField 适用于所有支持的数据库后端。

Django 现在包含 [`models.JSONField`](/zh-hans/4.2/ref/models/fields/#django.db.models.JSONField) 和 [`forms.JSONField`](/zh-hans/4.2/ref/forms/fields/#django.forms.JSONField)，可以在所有支持的数据库后端使用。这两个字段都支持使用自定义 JSON 编码器和解码器。模型字段支持自省、[查找和变换](/zh-hans/4.2/topics/db/queries/#querying-jsonfield)，这些功能以前只有 PostgreSQL 才有：

```
from django.db import models

class ContactInfo(models.Model):
    data = models.JSONField()

ContactInfo.objects.create(
    data={
        "name": "John",
        "cities": ["London", "Cambridge"],
        "pets": {"dogs": ["Rufus", "Meg"]},
    }
)
ContactInfo.objects.filter(
    data__name="John",
    data__pets__has_key="dogs",
    data__cities__contains="London",
).delete()
```

如果你的项目使用了 `django.contrib.postgres.fields.JSONField`，加上相关的表单字段和变换，你应该调整使用新的字段，并生成和应用数据库迁移。目前，旧的字段和变换体作为新字段的引用留存下来，并且 [从这个版本开始取消](#deprecated-jsonfield)。

### `DEFAULT_HASHING_ALGORITHM` 配置

新的 `DEFAULT_HASHING_ALGORITHM` 过渡设置允许指定用于编码 cookie、管理员站点中的密码重置令牌、用户会话以及由 [`django.core.signing.Signer`](/zh-hans/4.2/topics/signing/#django.core.signing.Signer) 和 [`django.core.signing.dumps()`](/zh-hans/4.2/topics/signing/#django.core.signing.dumps) 创建的签名的默认哈希算法。

在 Django 3.1 中添加了对 SHA-256 的支持。如果您正在将同一项目的多个实例升级到 Django 3.1，您应该在过渡期间将 `DEFAULT_HASHING_ALGORITHM` 设置为 `'sha1'`，以便与旧版本的 Django 兼容。请注意，这需要 Django 3.1.1+。一旦完成到 3.1 的过渡，您可以停止覆盖 `DEFAULT_HASHING_ALGORITHM`。

因为在 Django 4.0 中，对使用 SHA-1 算法的令牌、cookie、会话和签名的支持将被取消，所以这个配置从这个版本开始就被取消了。

### 次要特性

#### [`django.contrib.admin`](/zh-hans/4.2/ref/contrib/admin/#module-django.contrib.admin)

- 新的 `django.contrib.admin.EmptyFieldListFilter` 为 [`ModelAdmin.list_filter`](/zh-hans/4.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter) 允许在管理的变更列表视图中过滤空值（空字符串和空值）。
- 管理员更改列表视图右侧的过滤器现在包含一个清除所有过滤器的链接。
- 管理员现在在大屏幕上有一个侧栏，以便于导航。它是默认启用的，但可以通过使用一个自定义的 `AdminSite` 和设置 [`AdminSite.enable_nav_sidebar`](/zh-hans/4.2/ref/contrib/admin/#django.contrib.admin.AdminSite.enable_nav_sidebar) 为 `False` 来禁用。

  渲染侧边栏需要访问当前请求，以便设置 CSS 和 ARIA 角色的负担。这就需要使用 [`OPTIONS`](/zh-hans/4.2/ref/settings/#std-setting-TEMPLATES-OPTIONS) 的 `'context_processors'` 选项中的 `'django.template.context_processors.request'`。
- 最初的空 `extra` 内联现在可以被删除，与动态创建的内联相同。
- `XRegExp` 从 2.0.0 版本升级到 3.2.0。
- jQuery 从 3.4.1 版本升级到 3.5.1。
- Select2 库从 4.0.7 版本升级到 4.0.13。

#### [`django.contrib.auth`](/zh-hans/4.2/topics/auth/#module-django.contrib.auth)

- PBKDF2 密码哈希的默认迭代次数从 180,000 增加到 216,000。
- 新的 [`PASSWORD_RESET_TIMEOUT`](/zh-hans/4.2/ref/settings/#std-setting-PASSWORD_RESET_TIMEOUT) 配置允许定义密码重置链接的有效秒数。我们鼓励这样做，而不是使用被废弃的 `PASSWORD_RESET_TIMEOUT_DAYS` 配置，后者将在 Django 4.0 中被删除。
- 密码重置机制现在使用 SHA-256 散列算法。在 Django 4.0 之前，对使用旧的散列算法的令牌的支持仍然存在。
- [`AbstractBaseUser.get_session_auth_hash()`](/zh-hans/4.2/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash) 现在使用 SHA-256 散列算法。在 Django 4.0 之前，对使用旧的散列算法的用户会话的支持仍然存在。

#### [`django.contrib.contenttypes`](/zh-hans/4.2/ref/contrib/contenttypes/#module-django.contrib.contenttypes)

- 新的 [`remove_stale_contenttypes --include-stale-apps`](/zh-hans/4.2/ref/django-admin/#cmdoption-remove_stale_contenttypes-include-stale-apps) 选项允许从以前安装的应用程序中删除陈旧的内容类型，这些应用程序已经从 [`INSTALLED_APPS`](/zh-hans/4.2/ref/settings/#std-setting-INSTALLED_APPS) 中删除。

#### [`django.contrib.gis`](/zh-hans/4.2/ref/contrib/gis/#module-django.contrib.gis)

- [`relate`](/zh-hans/4.2/ref/contrib/gis/geoquerysets/#std-fieldlookup-relate) 查找现已在 MariaDB 上支持。
- 添加了 [`LinearRing.is_counterclockwise`](/zh-hans/4.2/ref/contrib/gis/geos/#django.contrib.gis.geos.LinearRing.is_counterclockwise) 属性。
- `AsGeoJSON` 现已在 Oracle 上支持。
- 添加了 `AsWKB` 和 `AsWKT` 函数。
- 增加了对 PostGIS 3 和 GDAL 3 的支持。

#### [`django.contrib.humanize`](/zh-hans/4.2/ref/contrib/humanize/#module-django.contrib.humanize)

- [`intword`](/zh-hans/4.2/ref/contrib/humanize/#std-templatefilter-intword) 模板过滤器现在支持负整数。

#### [`django.contrib.postgres`](/zh-hans/4.2/ref/contrib/postgres/#module-django.contrib.postgres)

- 新的 [`BloomIndex`](/zh-hans/4.2/ref/contrib/postgres/indexes/#django.contrib.postgres.indexes.BloomIndex) 类允许在数据库中创建 `bloom` 索引。新的 [`BloomExtension`](/zh-hans/4.2/ref/contrib/postgres/operations/#django.contrib.postgres.operations.BloomExtension) 迁移操作安装 `bloom` 扩展来增加对该索引的支持。
- [`get_FOO_display()`](/zh-hans/4.2/ref/models/instances/#django.db.models.Model.get_FOO_display) 现在支持 `ArrayField` 和 `RangeField`。
- 新的 [`rangefield.lower_inc`](/zh-hans/4.2/ref/contrib/postgres/fields/#std-fieldlookup-rangefield.lower_inc), [`rangefield.lower_inf`](/zh-hans/4.2/ref/contrib/postgres/fields/#std-fieldlookup-rangefield.lower_inf)、[`rangefield.upper_inc`](/zh-hans/4.2/ref/contrib/postgres/fields/#std-fieldlookup-rangefield.upper_inc) 和 [`rangefield.upper_inf`](/zh-hans/4.2/ref/contrib/postgres/fields/#std-fieldlookup-rangefield.upper_inf) 查找允许通过绑定类型查询 `RangeField`。
- [`rangefield.contained_by`](/zh-hans/4.2/ref/contrib/postgres/fields/#std-fieldlookup-rangefield.contained_by) 现在支持 [`SmallAutoField`](/zh-hans/4.2/ref/models/fields/#django.db.models.SmallAutoField)、[`AutoField`](/zh-hans/4.2/ref/models/fields/#django.db.models.AutoField)、[`BigAutoField`](/zh-hans/4.2/ref/models/fields/#django.db.models.BigAutoField)、[`SmallIntegerField`](/zh-hans/4.2/ref/models/fields/#django.db.models.SmallIntegerField) 和 [`DecimalField`](/zh-hans/4.2/ref/models/fields/#django.db.models.DecimalField)。
- [`SearchQuery`](/zh-hans/4.2/ref/contrib/postgres/search/#django.contrib.postgres.search.SearchQuery) 现在支持 PostgreSQL 11+ 上的 `'websearch'` 搜索类型。
- [`SearchQuery.value`](/zh-hans/4.2/ref/contrib/postgres/search/#django.contrib.postgres.search.SearchQuery) 现在支持查询表达式。
- 新的 [`SearchHeadline`](/zh-hans/4.2/ref/contrib/postgres/search/#django.contrib.postgres.search.SearchHeadline) 类可以高亮显示搜索结果。
- [`search`](/zh-hans/4.2/ref/contrib/postgres/search/#std-fieldlookup-search) 查找现在支持查询表达式。
- 新的 [`SearchRank`](/zh-hans/4.2/ref/contrib/postgres/search/#django.contrib.postgres.search.SearchRank) 的 `cover_density` 参数允许按覆盖密度进行排名。
- [`SearchRank`](/zh-hans/4.2/ref/contrib/postgres/search/#django.contrib.postgres.search.SearchRank) 的新 `normalization` 参数允许进行排名规范化。
- 新的 [`ExclusionConstraint.deferrable`](/zh-hans/4.2/ref/contrib/postgres/constraints/#django.contrib.postgres.constraints.ExclusionConstraint.deferrable) 属性允许创建可推迟的排除约束。

#### [`django.contrib.sessions`](/zh-hans/4.2/topics/http/sessions/#module-django.contrib.sessions)

- [`SESSION_COOKIE_SAMESITE`](/zh-hans/4.2/ref/settings/#std-setting-SESSION_COOKIE_SAMESITE) 配置现在允许 `'None'` （字符串）值明确表示所有同站和跨站请求都会发送 cookie。

#### [`django.contrib.staticfiles`](/zh-hans/4.2/ref/contrib/staticfiles/#module-django.contrib.staticfiles)

- [`STATICFILES_DIRS`](/zh-hans/4.2/ref/settings/#std-setting-STATICFILES_DIRS) 配置现在支持 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)。

#### 缓存

- 根据 [**RFC 7234 Section 5.2.2.2**](https://datatracker.ietf.org/doc/html/rfc7234.html#section-5.2.2.2)，[`cache_control()`](/zh-hans/4.2/topics/http/decorators/#django.views.decorators.cache.cache_control) 装饰器和 [`patch_cache_control()`](/zh-hans/4.2/ref/utils/#django.utils.cache.patch_cache_control) 方法现在支持 `Cache-Control` 头的 `no-cache` 指令中的多个字段名。
- [`delete()`](/zh-hans/4.2/topics/cache/#django.core.cache.cache.delete) 现在在成功删除键时返回 `True`，否则返回 `False`。

#### CSRF

- [`CSRF_COOKIE_SAMESITE`](/zh-hans/4.2/ref/settings/#std-setting-CSRF_COOKIE_SAMESITE) 配置现在允许 `'None'` （字符串）值来明确说明所有同站和跨站请求都会发送 cookie。

#### 电子邮件

- [附件邮件后端](/zh-hans/4.2/topics/email/#topic-email-file-backend) 使用的 [`EMAIL_FILE_PATH`](/zh-hans/4.2/ref/settings/#std-setting-EMAIL_FILE_PATH) 配置，现在支持 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)。

#### 错误报告

- `django.view.debug.SafeExceptionReporterFilter` 现在可以过滤异常报告中 `request.META` 中的敏感值。
- 新的 [`SafeExceptionReporterFilter.cleansed_substitute`](/zh-hans/4.2/howto/error-reporting/#django.views.debug.SafeExceptionReporterFilter.cleansed_substitute) 和 [`SafeExceptionReporterFilter.hidden_settings`](/zh-hans/4.2/howto/error-reporting/#django.views.debug.SafeExceptionReporterFilter.hidden_settings) 属性允许在异常报告中自定义敏感配置和 `request.META` 过滤。
- 在应用配置过滤时，技术 404 调试视图现在尊重 [`DEFAULT_EXCEPTION_REPORTER_FILTER`](/zh-hans/4.2/ref/settings/#std-setting-DEFAULT_EXCEPTION_REPORTER_FILTER)。
- 新的 [`DEFAULT_EXCEPTION_REPORTER`](/zh-hans/4.2/ref/settings/#std-setting-DEFAULT_EXCEPTION_REPORTER) 允许提供 [`django.views.debug.ExceptionReporter`](/zh-hans/4.2/howto/error-reporting/#django.views.debug.ExceptionReporter) 子类来定制异常报告的生成。详情请参见 [自定义错误报告](/zh-hans/4.2/howto/error-reporting/#custom-error-reports)。

#### 文件存储

- `FileSystemStorage.save()` 方法现在支持 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)。
- [`FileField`](/zh-hans/4.2/ref/models/fields/#django.db.models.FileField) 和 [`ImageField`](/zh-hans/4.2/ref/models/fields/#django.db.models.ImageField) 现在可以接受 `storage` 的调用。这允许你在运行时修改所使用的存储，例如为不同的环境选择不同的存储。

#### 表单

- [`ModelChoiceIterator`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceIterator)，被 [`ModelChoiceField`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceField) 和 [`ModelMultipleChoiceField`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelMultipleChoiceField) 使用，现在使用 [`ModelChoiceIteratorValue`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceIteratorValue)，可以被部件用来访问模型实例。详情请看 [迭代关系选择](/zh-hans/4.2/ref/forms/fields/#iterating-relationship-choices)。
- [`django.forms.DateTimeField`](/zh-hans/4.2/ref/forms/fields/#django.forms.DateTimeField) 现在接受 ISO 8601 日期时间格式的子集，包括可选的时区，例如 `2019-10-10T06:47`、`2019-10-10T06:47:23+04:00` 或 `2019-10-10T06:47:23Z`。如果提供了时区，将始终保留时区，即使 [`USE_TZ`](/zh-hans/4.2/ref/settings/#std-setting-USE_TZ) 为 `False` 时，也会返回时区感知的日期时间。

  此外，`DateTimeField` 现在在将字段输入转换为 `datetime` 值时，除了使用 `DATETIME_INPUT_FORMATS` 外，还使用 `DATE_INPUT_FORMATS`。
- [`MultiWidget.widgets`](/zh-hans/4.2/ref/forms/widgets/#django.forms.MultiWidget.widgets) 现在接受一个字典，允许自定义子部件 `name` 属性。
- 新的 [`BoundField.widget_type`](/zh-hans/4.2/ref/forms/api/#django.forms.BoundField.widget_type) 属性可用于根据部件类型动态调整表单渲染。

#### 国际化

- [`LANGUAGE_COOKIE_SAMESITE`](/zh-hans/4.2/ref/settings/#std-setting-LANGUAGE_COOKIE_SAMESITE) 配置现在允许 `'None'` （字符串）值明确表示所有同站和跨站请求都会发送 cookie。
- 增加了对阿尔及利亚阿拉伯语、伊博语、吉尔吉斯语、塔吉克语和土库曼语的支持和翻译。

#### 管理命令

- 新的 [`check --database`](/zh-hans/4.2/ref/django-admin/#cmdoption-check-database) 选项允许指定数据库别名，以便运行 `database` 系统检查。以前，通过向命令传递 `database` 标签，为所有设置的 [`DATABASES`](/zh-hans/4.2/ref/settings/#std-setting-DATABASES) 启用这些检查。
- 新的 [`migrate --check`](/zh-hans/4.2/ref/django-admin/#cmdoption-migrate-check) 选项使命令在检测到未应用的迁移时以非零状态退出。
- [`CommandError`](/zh-hans/4.2/howto/custom-management-commands/#django.core.management.CommandError) 的新 returncode\`\`参数允许自定义管理命令的退出状态。
- 新的 [`dbshell -- ARGUMENTS`](/zh-hans/4.2/ref/django-admin/#cmdoption-dbshell-0) 选项允许向数据库的命令行客户端传递额外的参数。
- [`flush`](/zh-hans/4.2/ref/django-admin/#django-admin-flush) 和 [`sqlflush`](/zh-hans/4.2/ref/django-admin/#django-admin-sqlflush) 命令现在包括 SQL 来重置 SQLite 上的序列。

#### 模型

- 新的 `ExtractIsoWeekDay` 函数从 [`DateField`](/zh-hans/4.2/ref/models/fields/#django.db.models.DateField) 和 [`DateTimeField`](/zh-hans/4.2/ref/models/fields/#django.db.models.DateTimeField) 中提取 ISO-8601 周天，新的 [`iso_week_day`](/zh-hans/4.2/ref/models/querysets/#std-fieldlookup-iso_week_day) 查询可以按 ISO-8601 周天查询。
- [`QuerySet.explain()`](/zh-hans/4.2/ref/models/querysets/#django.db.models.query.QuerySet.explain) 现在支持：

  - MySQL 8.0.16+ 上的 `TREE` 格式，
  - MySQL 8.0.18+ 和 MariaDB 上的 `analyze` 选项。
- 添加了 [`PositiveBigIntegerField`](/zh-hans/4.2/ref/models/fields/#django.db.models.PositiveBigIntegerField)，它的作用很像 [`PositiveIntegerField`](/zh-hans/4.2/ref/models/fields/#django.db.models.PositiveIntegerField)，只是它只允许在一定（依赖于数据库的）限制下取值。从 `0` 到 `9223372036854775807` 的值在 Django 支持的所有数据库中都是安全的。
- 新的 [`RESTRICT`](/zh-hans/4.2/ref/models/fields/#django.db.models.RESTRICT) 选项为 `` ForeignKey` `` 和 `OneToOneField` 的 [`on_delete`](/zh-hans/4.2/ref/models/fields/#django.db.models.ForeignKey.on_delete) 参数模拟了 SQL 约束 `ON DELETE RESTRICT` 的行为。
- [`CheckConstraint.check`](/zh-hans/4.2/ref/models/constraints/#django.db.models.CheckConstraint.check) 现在支持布尔表达式。
- [`RelatedManager.add()`](/zh-hans/4.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.add)、[`create()`](/zh-hans/4.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.create) 和 [`set()`](/zh-hans/4.2/ref/models/relations/#django.db.models.fields.related.RelatedManager.set) 方法现在接受可调用对象参数作为 `through_defaults` 参数的值。
- [`QuerySet.datetimes()`](/zh-hans/4.2/ref/models/querysets/#django.db.models.query.QuerySet.datetimes) 的新 `is_dst` 参数决定了如何处理不存在和不明确的日期。
- 新的 [`F`](/zh-hans/4.2/ref/models/expressions/#django.db.models.F) 表达式 `bitxor()` 方法允许 [bitwise XOR 操作](/zh-hans/4.2/topics/db/queries/#using-f-expressions-in-filters)。
- [`QuerySet.bulk_create()`](/zh-hans/4.2/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create) 在使用 MariaDB 10.5+ 时，现在可以设置对象的主键。
- `DatabaseOperations.sql_flush()` 方法现在可以在 MySQL 上生成更有效的 SQL，对于不需要重置序列的表，使用 `DELETE` 而不是 `TRUNCATE` 语句。
- SQLite 函数现已在 Python 3.8+ 上被标记为 [`deterministic`](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function)。这允许在检查约束和部分索引中使用它们。
- 新的 [`UniqueConstraint.deferrable`](/zh-hans/4.2/ref/models/constraints/#django.db.models.UniqueConstraint.deferrable) 属性允许创建可推迟的唯一约束。

#### 分页

- [`Paginator`](/zh-hans/4.2/ref/paginator/#django.core.paginator.Paginator) 现在可以迭代产生其页面。

#### 请求和响应

- 如果 [`ALLOWED_HOSTS`](/zh-hans/4.2/ref/settings/#std-setting-ALLOWED_HOSTS) 为空且 `DEBUG=True`，则在 `Host` 头中允许使用 localhost 的子域，例如 `static.localhost`。
- [`HttpResponse.set_cookie()`](/zh-hans/4.2/ref/request-response/#django.http.HttpResponse.set_cookie) 和 [`HttpResponse.set_signed_cookie()`](/zh-hans/4.2/ref/request-response/#django.http.HttpResponse.set_signed_cookie) 现在允许使用 `samesite='None'` （字符串）来明确说明所有同站和跨站请求都会发送cookie。
- 新的 [`HttpRequest.accepts()`](/zh-hans/4.2/ref/request-response/#django.http.HttpRequest.accepts) 方法根据 `Accept` HTTP 头返回请求是否接受给定的 MIME 类型。

#### 安全

- [`SECURE_REFERRER_POLICY`](/zh-hans/4.2/ref/settings/#std-setting-SECURE_REFERRER_POLICY) 配置现在默认为 `'same-origin'`。设置了这个之后，[`SecurityMiddleware`](/zh-hans/4.2/ref/middleware/#django.middleware.security.SecurityMiddleware) 会在所有还没有设置 [Referrer 政策](/zh-hans/4.2/ref/middleware/#referrer-policy) 头的情况下，将其设置为 `same-origin`。这可以防止 `Referer` 头被发送到其他来源。如果你需要以前的行为，明确地设置 [`SECURE_REFERRER_POLICY`](/zh-hans/4.2/ref/settings/#std-setting-SECURE_REFERRER_POLICY) 为 `None`。
- [`django.core.signing.Signer`](/zh-hans/4.2/topics/signing/#django.core.signing.Signer)、`django.core.signing.load()` 和 [`django.core.signing.dumps()`](/zh-hans/4.2/topics/signing/#django.core.signing.dumps) 的默认算法改为 SHA-256。在 Django 4.0 之前，仍然支持用旧的 SHA-1 算法进行签名。

  另外，[`Signer`](/zh-hans/4.2/topics/signing/#django.core.signing.Signer) 的新 `algorithm` 参数允许自定义哈希算法。

#### 模板

- 重新命名的 [`translate`](/zh-hans/4.2/topics/i18n/translation/#std-templatetag-translate) 和 [`blocktranslate`](/zh-hans/4.2/topics/i18n/translation/#std-templatetag-blocktranslate) 模板标签被引入，用于模板代码的国际化。旧的 [`trans`](/zh-hans/4.2/topics/i18n/translation/#std-templatetag-trans) 和 [`blocktrans`](/zh-hans/4.2/topics/i18n/translation/#std-templatetag-blocktrans) 模板标签的别名继续工作，并将在可预见的未来保留。
- [`include`](/zh-hans/4.2/ref/templates/builtins/#std-templatetag-include) 模板标签现在接受模板名称的可迭代对象。

#### 测试

- [`SimpleTestCase`](/zh-hans/4.2/topics/testing/tools/#django.test.SimpleTestCase) 现在实现了 `debug()` 方法，允许在不收集结果和捕获异常的情况下运行测试。这可以用来支持在调试器下运行测试。
- 新的 [`MIGRATE`](/zh-hans/4.2/ref/settings/#std-setting-TEST_MIGRATE) 测试数据库配置允许在创建测试数据库时禁止迁移。
- Django 测试运行器现在支持 [`test --buffer`](/zh-hans/4.2/ref/django-admin/#cmdoption-test-buffer) 选项，以丢弃通过测试的输出。
- [`DiscoverRunner`](/zh-hans/4.2/topics/testing/advanced/#django.test.runner.DiscoverRunner) 现在会跳过对非 [测试所引用](/zh-hans/4.2/topics/testing/tools/#testing-multi-db) 的数据库进行系统检查。
- [`TransactionTestCase`](/zh-hans/4.2/topics/testing/tools/#django.test.TransactionTestCase) 关闭现在在 MySQL 上的速度更快了，这是因为 [`flush`](/zh-hans/4.2/ref/django-admin/#django-admin-flush) 命令的改进。作为一个副作用，后者不会再在关闭时自动重置序列。如果你的测试需要这个功能，请启用 [`TransactionTestCase.reset_sequences`](/zh-hans/4.2/topics/testing/advanced/#django.test.TransactionTestCase.reset_sequences)。

#### URLs

- [Path 转换器](/zh-hans/4.2/topics/http/urls/#registering-custom-path-converters) 现在可以在 `to_url()` 中引发 `ValueError`，在反查 URL 时表示不匹配。

#### 实用程序

- [`filepath_to_uri()`](/zh-hans/4.2/ref/utils/#django.utils.encoding.filepath_to_uri) 现在支持 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)。
- [`parse_duration()`](/zh-hans/4.2/ref/utils/#django.utils.dateparse.parse_duration) 现在支持 ISO 8601 格式的小数点用逗号分隔。
- [`parse_datetime()`](/zh-hans/4.2/ref/utils/#django.utils.dateparse.parse_datetime)、[`parse_duration()`](/zh-hans/4.2/ref/utils/#django.utils.dateparse.parse_duration) 和 [`parse_time()`](/zh-hans/4.2/ref/utils/#django.utils.dateparse.parse_time) 现在支持用逗号分隔毫秒。

#### 杂项

- SQLite 后端现在支持 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path) 为 `NAME` 的配置。
- 由 [`startproject`](/zh-hans/4.2/ref/django-admin/#django-admin-startproject) 命令生成的 `settings.py` 现在使用 [`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path) 代替 [`os.path`](https://docs.python.org/3/library/os.path.html#module-os.path) 来建立文件系统路径。
- 现在允许在支持时区的数据库上进行 [`TIME_ZONE`](/zh-hans/4.2/ref/settings/#std-setting-DATABASE-TIME_ZONE) 设置。

## 3.1 中的不向后兼容的变更

### 数据库后端 API

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

- `DatabaseOperations.fetch_returned_insert_columns()` 现在需要一个额外的 `returning_params` 参数。
- `connection.timezone` 属性现在默认为 `'UTC`，或者当 [`USE_TZ`](/zh-hans/4.2/ref/settings/#std-setting-USE_TZ) 为 `True` 时，支持时区的数据库上的 [`TIME_ZONE`](/zh-hans/4.2/ref/settings/#std-setting-DATABASE-TIME_ZONE)。此前，在支持时区的数据库上是 `None`。
- `connection._nodb_connection` 属性改为 `connection._nodb_cursor()` 方法，现在返回一个产生游标的上下文管理器，并在退出 `with` 语句后自动关闭游标和连接。
- `DatabaseClient.runshell()` 现在需要一个额外的 `parameters` 参数，作为传递给命令行客户端的额外参数列表。
- `DatabaseOperations.sql_flush()` 的 `sequences` 位置参数被只用关键字的布尔参数 `reset_sequences` 取代。如果 `True`，截断表的序列将被重置。
- `DatabaseOperations.sql_flush()` 的 `allow_cascade` 参数现在是一个纯关键字的参数。
- `DatabaseOperations.execute_sql_flush()` 的 `using` 位置参数被删除。该方法现在使用被调用实例的数据库。
- 第三方数据库后端必须实现对 `JSONField` 的支持，或者将 `DatabaseFeatures.supports_json_field` 设置为 `False`。如果不支持存储基元，则设置 `DatabaseFeatures.supports_primitives_in_json_field` 为 `False`。如果 JSON 的数据类型为真，则设置 `DatabaseFeatures.has_native_json_field` 为 `True`。如果不支持 [`jsonfield.contains`](/zh-hans/4.2/topics/db/queries/#std-fieldlookup-jsonfield.contains) 和 `jsonfield.contains_by`，则将 `DatabaseFeatures.support_json_field_contains` 设置为 `False`。
- 第三方数据库后端必须实现对 `JSONField` 的自省，或者将 `can_introspect_json_field` 设置为 `False`。

### 丢弃了对 MariaDB 10.1 的支持

对 MariaDB 10.1 的上游支持在 2020 年 10 月结束。Django 3.1 支持 MariaDB 10.2 及以上版本。

### `contrib.admin` 浏览器支持

管理不再支持传统的 Internet Explorer 浏览器。关于支持的浏览器，请参见 [管理常见问题](/zh-hans/4.2/faq/admin/#admin-browser-support)。

### [`AbstractUser.first_name`](/zh-hans/4.2/ref/contrib/auth/#django.contrib.auth.models.User.first_name) 的 `max_length` 增加到 150

包含了 [`django.contrib.auth.models.User.first_name`](/zh-hans/4.2/ref/contrib/auth/#django.contrib.auth.models.User.first_name) 的迁移。如果你有一个继承自 `AbstractUser` 的自定义用户模型，你将需要为你的用户模型生成并应用数据库迁移。

如果你想保留 first name 的 30 个字符限制，请使用自定义表单：

```
from django import forms
from django.contrib.auth.forms import UserChangeForm

class MyUserChangeForm(UserChangeForm):
    first_name = forms.CharField(max_length=30, required=False)
```

如果你想在管理中编辑用户时保留这个限制，请将 `UserAdmin.form` 设置为使用这个表单：

```
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm

admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
```

### 杂项

- [`cache`](/zh-hans/4.2/topics/cache/#std-templatetag-cache) 使用的缓存密钥和 [`make_template_fragment_key()`](/zh-hans/4.2/topics/cache/#django.core.cache.utils.make_template_fragment_key) 生成的缓存密钥与旧版本 Django 生成的密钥不同。升级到 Django 3.1 后，第一次请求任何之前缓存的模板片段都会被缓存错过。
- 从 [`set_language()`](/zh-hans/4.2/topics/i18n/translation/#django.views.i18n.set_language) 视图中返回重定向回退或 204 HTTP 响应背后的逻辑现在是基于 `Accept` HTTP 头而不是 `X-Requested-With` HTTP 头的存在。
- `django.db.models.query`、`django.db.models.sql` 和 `django.db.models.sql.datastructures` 中的 `django.core.exceptions.EmptyResultSet` 的兼容性导入被移除。
- 删除了 `django.db.models.field` 中 `django.core.exceptions.FieldDoesNotExist` 的兼容性导入。
- 删除了 `django.forms.utils.pretty_name()` 和 `django.forms.boundfield.BoundField` 的兼容性导入。
- `django.template.base` 中的 `Context`、`ContextPopException` 和 `RequestContext` 的兼容性导入被移除。
- 删除了 `django.contrib.admin.helpers.ACTION_CHECKBOX_NAME` 中的兼容性导入。
- 设置为相对路径的 [`STATIC_URL`](/zh-hans/4.2/ref/settings/#std-setting-STATIC_URL) 和 [`MEDIA_URL`](/zh-hans/4.2/ref/settings/#std-setting-MEDIA_URL) 配置现在以服务器提供的 `SCRIPT_NAME` 的值为前缀（如果没有设置，则为 `/`）。这一变化不应影响设置为有效 URL 或绝对路径的配置。
- [`ConditionalGetMiddleware`](/zh-hans/4.2/ref/middleware/#django.middleware.http.ConditionalGetMiddleware) 不再为空 [`content`](/zh-hans/4.2/ref/request-response/#django.http.HttpResponse.content) 的响应添加 `ETag` 头。
- `django.utils.disturators.classproperty()` 装饰器被公开并移到 [`django.utils.functional.classproperty()`](/zh-hans/4.2/ref/utils/#django.utils.functional.classproperty)。
- `floatform` 模板过滤器现在对四舍五入为零的负数输出（正）\`\`0\`\`\`。
- [`Meta.ordering`](/zh-hans/4.2/ref/models/options/#django.db.models.Options.ordering) 和 `` Meta.unique_together <django.db.models.Options.unique_together>` `` 模块中模型的选项，以前是元组，现在是列表。
- 管理日历部件现在根据开放组规范处理两位数的年份，即 69 和 99 之间的值被映射到上一个世纪，0 和 68 之间的值被映射到当前世纪。
- 从 [`DATETIME_INPUT_FORMATS`](/zh-hans/4.2/ref/settings/#std-setting-DATETIME_INPUT_FORMATS) 的默认列表中删除了仅限日期的格式。
- 当初始数据存在时，[`FileInput`](/zh-hans/4.2/ref/forms/widgets/#django.forms.FileInput) 小部件不再使用 `required` HTML 属性进行渲染。
- 删除了未记录的 `django.views.debug.ExceptionReporterFilter` 类。根据 [自定义错误报告](/zh-hans/4.2/howto/error-reporting/#custom-error-reports) 文档，与 [`DEFAULT_EXCEPTION_REPORTER_FILTER`](/zh-hans/4.2/ref/settings/#std-setting-DEFAULT_EXCEPTION_REPORTER_FILTER) 一起使用的类需要继承 [`django.views.debug.SafeExceptionReporterFilter`](/zh-hans/4.2/howto/error-reporting/#django.views.debug.SafeExceptionReporterFilter)。
- [`cache_page()`](/zh-hans/4.2/topics/cache/#django.views.decorators.cache.cache_page) 装饰器设置的缓存超时现在优先于 `Cache-Control` 头的 `max-age` 指令。
- 在 [`ForeignKey.to_field`](/zh-hans/4.2/ref/models/fields/#django.db.models.ForeignKey.to_field) 参数中提供一个非本地的远程字段，现在会引发 [`FieldError`](/zh-hans/4.2/ref/exceptions/#django.core.exceptions.FieldError)。
- [`SECURE_REFERRER_POLICY`](/zh-hans/4.2/ref/settings/#std-setting-SECURE_REFERRER_POLICY) 现在默认为 `'same-origin'`。更多细节请参见 *新变化* [安全章节](#whats-new-security-3-1)。
- [`check`](/zh-hans/4.2/ref/django-admin/#django-admin-check) 管理命令现在只对使用 [`check --database`](/zh-hans/4.2/ref/django-admin/#cmdoption-check-database) 选项指定的数据库别名运行 `database` 系统检查。
- [`migrate`](/zh-hans/4.2/ref/django-admin/#django-admin-migrate) 管理命令现在只运行 `database` 系统检查要迁移的数据库。
- 管理 CSS 类 `row1` 和 `row2` 被删除，取而代之的是 `:nth-child(odd)` 和 `:nth-child(even)` 伪类。
- [`make_password()`](/zh-hans/4.2/topics/auth/passwords/#django.contrib.auth.hashers.make_password) 函数现在要求其参数为字符串或字节。其他类型的参数应该显式地转换为其中之一。
- 删除了 `AsKML` 函数中未记录的 `version` 参数。
- [JSON 和 YAML 序列化器](/zh-hans/4.2/topics/serialization/#serialization-formats)，由 [`dumpdata`](/zh-hans/4.2/ref/django-admin/#django-admin-dumpdata) 使用，现在默认使用 Unicode 转储所有数据。如果你需要以前的行为，传递 `ensure_ascii=True` 给 JSON 序列化器，或者 `allow_unicode=False` 给 YAML 序列化器。
- 自动重新加载器不再监控内置 Django 翻译文件的变化。
- `mysqlclient` 的最低支持版本从 1.3.13 增加到 1.4.0。
- 未记录的 `django.contrib.postgres.forms.InvalidJSONInput` 和 `django.contrib.postgres.forms.JSONString` 被移至 `django.forms.field`。
- 删除了未记录的 `django.contrib.postgres.field.jsonb.JsonAdapter` 类。
- [`{% localize off %}`](/zh-hans/4.2/topics/i18n/formatting/#std-templatetag-localize) 标签和 [`unlocalize`](/zh-hans/4.2/topics/i18n/formatting/#std-templatefilter-unlocalize) 过滤器不再遵守 [`DECIMAL_SEPARATOR`](/zh-hans/4.2/ref/settings/#std-setting-DECIMAL_SEPARATOR) 配置。
- `asgiref` 的最低支持版本从 3.2 增加到 3.2.10。
- [Media](/zh-hans/4.2/topics/forms/media/) 类现在不使用 `type` 属性来渲染 `<script>` 标签，以遵循 [WHATWG 建议](https://html.spec.whatwg.org/multipage/scripting.html#the-script-element) 。
- [`ModelChoiceIterator`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceIterator)，由 [`ModelChoiceField`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceField) 和 [`ModelMultipleChoiceField`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelMultipleChoiceField) 使用，现在产生 2 个包含 [`ModelChoiceIteratorValue`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceIteratorValue) 实例的选择，作为每个选择的第一个 `value` 元素。在大多数情况下，这个代理是透明的，但如果你需要 `field` 值本身，请使用 [`ModelChoiceIteratorValue.value`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelChoiceIteratorValue.value) 属性代替。

## 在 3.1 中被废弃的功能

### PostgreSQL 的 `JSONField`

`django.contrib.postgres.field.JSONField` 和 `django.contrib.postgres.forms.JSONField` 被废弃，改用 [`models.JSONField`](/zh-hans/4.2/ref/models/fields/#django.db.models.JSONField) 和 [`forms.JSONField`](/zh-hans/4.2/ref/forms/fields/#django.forms.JSONField)。

未记录的 `django.contrib.postgres.fields.jsonb.KeyTransform` 和 `django.contrib.postgres.fields.jsonb.KeyTextTransform` 也被弃用，改用 `django.db.models.fields.json` 中的变换。

新的 `JSONField`、`KeyTransform` 和 `KeyTextTransform` 可用于所有支持的数据库后端。

### 杂项

- `PASSWORD_RESET_TIMEOUT_DAYS` 配置已被取消，改为 [`PASSWORD_RESET_TIMEOUT`](/zh-hans/4.2/ref/settings/#std-setting-PASSWORD_RESET_TIMEOUT)。
- 未记录的 [`isnull`](/zh-hans/4.2/ref/models/querysets/#std-fieldlookup-isnull) 查找使用非布尔值作为右侧的用法已被废弃，请使用 `True` 或 `False` 代替。
- 勉强记录的 `django.db.models.query_utils.InvalidQuery` 异常类被废弃，取而代之的是 [`FieldDoesNotExist`](/zh-hans/4.2/ref/exceptions/#django.core.exceptions.FieldDoesNotExist) 和 [`FieldError`](/zh-hans/4.2/ref/exceptions/#django.core.exceptions.FieldError)。
- `django-admin.py` 的入口点已被废弃，改为 `django-admin`。
- `HttpRequest.is_ajax()` 方法已被废弃，因为它依赖于 jQuery 特定的方式来表示 AJAX 调用，而当前的用法倾向于使用 JavaScript [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) 。根据你的用例，你可以写你自己的 AJAX 检测方法，或者使用新的 [`HttpRequest.accepts()`](/zh-hans/4.2/ref/request-response/#django.http.HttpRequest.accepts) 方法，如果你的代码依赖于客户端 `Accept` HTTP 头。

  如果你正在编写自己的 AJAX 检测方法，`request.is_ajax()` 可以完全复制为 `request.headers.get('x-requested-with') == 'XMLHttpRequest'`。
- 传递 `None` 作为 `django.utils.deprecation.MiddlewareMixin.__init__()` 的第一个参数是过时的。
- [`CookieStorage`](/zh-hans/4.2/ref/contrib/messages/#django.contrib.messages.storage.cookie.CookieStorage) 使用的 cookie 值的编码格式与旧版本 Django 生成的格式不同。在 Django 4.0 之前，仍然支持旧的格式。
- 会话的编码格式与旧版 Django 生成的格式不同。在 Django 4.0 之前，仍然支持旧的格式。
- [`Signal`](/zh-hans/4.2/topics/signals/#django.dispatch.Signal) 的纯文档化 `providing_args` 参数已被废弃。如果你依赖这个参数作为文档，你可以将文本移到代码注释或 docstring 中。
- 没有 `length` 参数的情况下调用 `django.utils.crypto.get_random_string()` 已被废弃。
- [`ModelMultipleChoiceField`](/zh-hans/4.2/ref/forms/fields/#django.forms.ModelMultipleChoiceField) 的 `list` 信息已被弃用，改为 `invalid_list`。
- 向 [`QuerySet.order_by()`](/zh-hans/4.2/ref/models/querysets/#django.db.models.query.QuerySet.order_by) 传递原始列别名已经被废弃。通过事先在 [`RawSQL`](/zh-hans/4.2/ref/models/expressions/#django.db.models.expressions.RawSQL) 中传递别名，可以达到同样的效果。
- `NullBooleanField` 模型字段被废弃，改为 `BooleanField(null=True)`。
- `django.conf.urls.url()` 的 [`django.urls.re_path()`](/zh-hans/4.2/ref/urls/#django.urls.re_path) 别名已被废弃。
- `{% ifequal %}` 和 `{% ifnotequal %}` 模板标签已被废弃，改为 [`{% if %}`](/zh-hans/4.2/ref/templates/builtins/#std-templatetag-if)。`{% if %}` 涵盖了所有的用例，但如果你需要继续使用这些标签，可以将它们从 Django 中提取到一个模块中，并作为一个内置标签包含在 [`'buildins'`](/zh-hans/4.2/topics/templates/#django.template.backends.django.DjangoTemplates) 选项中的 [`OPTIONS`](/zh-hans/4.2/ref/settings/#std-setting-TEMPLATES-OPTIONS) 中。
- `DEFAULT_HASHING_ALGORITHM` 过渡性配置已废弃。

## 3.1 中删除的功能

这些功能已经到了废弃周期，在 Django 3.1 中被删除。

参见 [在 2.2 中被废弃的功能](/zh-hans/4.2/releases/2.2/#deprecated-features-2-2)，了解这些变化的细节，包括如何删除这些功能的使用。

- `django.utils.timezone.FixedOffset` 被删除。
- `django.core.paginator.QuerySetPaginator` 被删除。
- 一个模型的 `Meta.ordering` 不影响 `GROUP BY` 的查询。
- `django.contrib.postgres.fields.FloatRangeField` 和 `django.contrib.postgres.forms.FloatRangeField` 被删除。
- `FILE_CHARSET` 配置被删除。
- `django.contrib.staticfiles.storage.CachedStaticFilesStorage` 被删除。
- `RemoteUserBackend.configure_user()` 方法需要 `request` 作为第一个位置参数。
- 取消对 `SimpleTestCase.allow_database_queries` 和 `TransactionTestCase.multi_db` 的支持。
