Django 3.2 发行说明 — Django 文档
Django 3.2 发行说明
2021 年 4 月 6 日
欢迎使用 Django 3.2!
这些发行说明涵盖了 新功能 ,以及从 Django 3.1 或更早版本升级时您需要注意的一些 向后不兼容更改 。 我们已经 开始了某些功能 的弃用过程。
如果您要更新现有项目,请参阅 将 Django 升级到更新版本 指南。
Django 3.2 被指定为 长期支持版本 。 它将在发布后至少三年内收到安全更新。 对之前的 LTS Django 2.2 的支持将于 2022 年 4 月结束。
Python兼容性
Django 3.2 支持 Python 3.6、3.7、3.8、3.9 和 3.10(从 3.2.9 开始)。 我们【X3X】强烈推荐【X23X】,官方只支持各系列的最新版本。
Django 3.2 中的新功能
自动 AppConfig 发现
大多数可插拔应用程序在 apps.py
子模块中定义了 AppConfig 子类。 许多人在他们的 __init__.py
中定义了一个指向这个类的 default_app_config
变量。
当 apps.py
子模块存在并定义单个 AppConfig 子类时,Django 现在会自动使用该配置,因此您可以删除 default_app_config
。
default_app_config
使得可以在 :setting:`INSTALLED_APPS` 中仅声明应用程序的路径(例如 'django.contrib.admin'
) 而不是应用配置的路径(例如 'django.contrib.admin.apps.AdminConfig'
)。 引入它是为了与前一种风格向后兼容,目的是将生态系统切换到后者,但这种切换没有发生。
通过自动发现 AppConfig
,不再需要 default_app_config
。 因此,它已被弃用。
有关完整详细信息,请参阅 配置应用程序 。
自定义自动创建的主键类型
定义模型时,如果模型中没有使用 primary_key=True 定义字段,则会添加隐式主键。 现在可以通过 :setting:`DEFAULT_AUTO_FIELD` 设置和 AppConfig.default_auto_field 属性控制此隐式主键的类型。 不再需要覆盖所有模型中的主键。
保持历史行为,:setting:`DEFAULT_AUTO_FIELD` 的默认值为 AutoField。 从 3.2 开始生成新项目,:setting:`DEFAULT_AUTO_FIELD` 设置为 BigAutoField。 此外,新应用程序是在 AppConfig.default_auto_field 设置为 BigAutoField 的情况下生成的。 在未来的 Django 版本中,:setting:`DEFAULT_AUTO_FIELD` 的默认值将更改为 BigAutoField。
为避免将来发生不必要的迁移,请将 :setting:`DEFAULT_AUTO_FIELD` 显式设置为 AutoField:
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
或在每个应用程序的基础上配置它:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
default_auto_field = 'django.db.models.AutoField'
name = 'my_app'
或基于每个模型:
from django.db import models
class MyModel(models.Model):
id = models.AutoField(primary_key=True)
预计会更改默认值,如果您没有 :setting:`DEFAULT_AUTO_FIELD` 的显式设置,系统检查将提供警告。
更改:setting:`DEFAULT_AUTO_FIELD` 的值时,当前无法生成通过表自动创建的现有主键的迁移。 有关迁移此类表的详细信息,请参阅 :setting:`DEFAULT_AUTO_FIELD` 文档。
功能索引
Index() 的新 *expressions 位置参数允许在表达式和数据库函数上创建函数索引。 例如:
from django.db import models
from django.db.models import F, Index, Value
from django.db.models.functions import Lower, Upper
class MyModel(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
height = models.IntegerField()
weight = models.IntegerField()
class Meta:
indexes = [
Index(
Lower('first_name'),
Upper('last_name').desc(),
name='first_last_name_idx',
),
Index(
F('height') / (F('weight') + Value(5)),
name='calc_idx',
),
]
使用 Meta.indexes 选项将功能索引添加到模型中。
pymemcache 支持
新的 django.core.cache.backends.memcached.PyMemcacheCache
缓存后端允许将 pymemcache 库用于 memcached。 pymemcache
需要 3.4.0 或更高版本。 有关更多详细信息,请参阅有关 Django 中缓存的 文档。
管理站点的新装饰器
新的 display() 装饰器允许轻松地将选项添加到可与 list_display 或 readonly_fields 一起使用的自定义显示函数。
同样,新的 action() 装饰器允许轻松地向可与 actions 一起使用的动作函数添加选项。
使用 @display
装饰器的优点是现在可以在需要在自定义方法上指定属性时使用 @property
装饰器。 在此之前,必须在为方法分配所需属性后使用 property()
函数。
使用装饰器的优点是这些选项更容易被发现,因为它们可以由代码编辑器中的完成实用程序建议。 它们只是一种方便,并且仍然在引擎盖下的函数上设置相同的属性。
小功能
django.contrib.admin
ModelAdmin.search_fields 现在允许搜索带空格的引用短语。
如果目标模型在管理中注册,只读相关字段现在呈现为可导航链接。
管理员现在支持主题,并包含根据浏览器设置启用的深色主题。 有关更多详细信息,请参阅 主题支持 。
ModelAdmin.autocomplete_fields 现在在搜索相关模型时尊重 ForeignKey.to_field 和 ForeignKey.limit_choices_to。
管理员现在安装一个最终的全能视图,将未经身份验证的用户重定向到登录页面,无论 URL 是否有效。 这可以防止潜在的模型枚举隐私问题。
虽然不推荐,但您可以将新的 AdminSite.final_catch_all_view 设置为
False
以禁用全能视图。
django.contrib.auth
PBKDF2 密码哈希器的默认迭代计数从 216,000 增加到 260,000。
Argon2 密码哈希器的默认变体更改为 Argon2id。
memory_cost
和parallelism
分别增加到 102,400 和 8 以匹配argon2-cffi
默认值。增加
memory_cost
会将所需的内存从 512 KB 推到 100 MB。 这仍然相当保守,但可能会导致内存受限环境中的问题。 如果是这种情况,现有的散列器可以被子类化以覆盖默认值。Argon2、MD5、PBKDF2、SHA-1 密码哈希的默认盐熵从 71 位增加到 128 位。
django.contrib.contenttypes
- generic_inlineformset_factory() 的新
absolute_max
参数允许自定义在提供POST
数据时可以实例化的最大表单数。 有关更多详细信息,请参阅 限制实例化表单的最大数量 。 - generic_inlineformset_factory() 的新
can_delete_extra
参数允许删除删除额外表单的选项。 有关更多信息,请参阅 can_delete_extra。
django.contrib.gis
- GDALRaster.transform() 方法现在支持 SpatialReference。
- DataSource 类现在支持
pathlib.Path
。 - LayerMapping 类现在支持
pathlib.Path
。
django.contrib.postgres
- 新的 ExclusionConstraint.include 属性允许在 PostgreSQL 12+ 上创建覆盖排除约束。
- 新的 ExclusionConstraint.opclasses 属性允许设置 PostgreSQL 操作符类。
- 新的 JSONBAgg.ordering 属性决定了聚合元素的顺序。
- 新的 JSONBAgg.distinct 属性确定聚合值是否不同。
- CreateExtension 操作现在检查扩展是否已存在于数据库中,如果存在则跳过迁移。
- 新的 CreateCollation 和 RemoveCollation 操作允许在 PostgreSQL 上创建和删除排序规则。 有关更多详细信息,请参阅 使用迁移 管理排序规则。
- ArrayField 的查找现在允许(非嵌套)包含表达式作为右侧的数组。
- 新的 OpClass() 表达式允许使用自定义运算符类在表达式上创建函数索引。 有关更多详细信息,请参阅 函数索引 。
django.contrib.sitemaps
- 新的 Sitemap 属性 alternates、languages 和 x_default 允许生成站点地图 alternates 到您的页面的本地化版本。
数据库后端
- 第三方数据库后端现在可以使用新的
DatabaseFeatures.django_test_skips
和django_test_expected_failures
属性跳过或标记 Django 测试套件中的预期失败测试。
表格
- formset_factory()、inlineformset_factory() 和 modelformset_factory() 的新
absolute_max
参数允许自定义最大表单数提供POST
数据时实例化。 有关更多详细信息,请参阅 限制实例化表单的最大数量 。 - formset_factory()、inlineformset_factory() 和 modelformset_factory() 的新
can_delete_extra
参数允许删除删除额外表单的选项。 有关更多信息,请参阅 can_delete_extra。 - BaseFormSet 现在在管理表单丢失或被篡改时报告用户面临的错误,而不是引发异常。 要自定义此错误消息,请在实例化表单集时使用
'missing_management_form'
键传递error_messages
参数。
管理命令
- :djadmin:`loaddata` 现在支持存储在 XZ 档案(
.xz
)和 LZMA 档案(.lzma
)中的装置。 - :djadmin:`dumpdata` 现在可以压缩
bz2
、gz
、lzma
或xz
格式的数据。 - :djadmin:`makemigrations` 现在可以在没有活动数据库连接的情况下调用。 在这种情况下,将跳过检查一致的迁移历史记录。
- BaseCommand.requires_system_checks 现在支持指定标签列表。 在执行命令之前,将检查在所选标签中注册的系统检查是否有错误。 在以前的版本中,要么执行所有系统检查,要么不执行任何系统检查。
- 更新了对 Windows 上彩色终端输出的支持。 自动检测各种现代终端环境,并改进了在其他情况下启用支持的选项。 有关更多详细信息,请参阅 语法着色 。
迁移
- 新的
Operation.migration_name_fragment
属性允许提供一个文件名片段,该片段将用于命名仅包含该操作的迁移。 - 迁移现在支持从
pathlib
和os.PathLike
实例序列化纯路径对象。
型号
- PostgreSQL 支持的 QuerySet.select_for_update() 的新
no_key
参数允许获取较弱的锁,这些锁不会阻止通过外键引用锁定行的行的创建。 - When() 表达式现在允许将
condition
参数与lookups
一起使用。 - 新的 Index.include 和 UniqueConstraint.include 属性允许在 PostgreSQL 11+ 上创建覆盖索引和覆盖唯一约束。
- 新的 UniqueConstraint.opclasses 属性允许设置 PostgreSQL 操作符类。
- QuerySet.update() 方法现在尊重 MySQL 和 MariaDB 上的
order_by()
子句。 - FilteredRelation() 现在支持嵌套关系。
- QuerySet.select_for_update() 的
of
参数现在在 MySQL 8.0.1+ 上是允许的。 - Value() 表达式现在根据其为
bool
提供的value
的类型自动将其output_field
解析为适当的 Field 子类]、bytes
、float
、int
、str
、datetime.date
、datetime.datetime
、[X224X] 、datetime.timedelta
、decimal.Decimal
和uuid.UUID
实例。 因此,在使用Value()
时,解析数据库函数和组合表达式的output_field
现在可能会因混合类型而崩溃。 在这种情况下,您需要明确设置output_field
。 - 新的 QuerySet.alias() 方法允许为不需要选择但用于过滤、排序或作为复杂表达式的一部分的表达式创建可重用的别名。
- 新的 Collate 函数允许按指定的数据库排序规则进行过滤和排序。
- 如果 QuerySet.distinct() 中只指定了一个字段,则 QuerySet.in_bulk() 的
field_name
参数现在接受不同的字段。 - TruncDate 和 TruncTime 数据库函数的新
tzinfo
参数允许在特定时区截断日期时间。 - CharField 和 TextField 的新
db_collation
参数允许为字段设置数据库排序规则。 - 添加了 Random 数据库功能。
- 聚合函数 、F()、OuterRef() 和其他表达式现在允许使用转换。 有关详细信息,请参阅 表达式可以参考变换 。
- atomic() 的新
durable
参数保证在原子块中所做的更改将在原子块无错误退出时提交。 标记为持久的嵌套原子块将引发RuntimeError
。 - 新增 JSONObject 数据库功能。
分页
- 新的 django.core.paginator.Paginator.get_elided_page_range() 方法允许生成一个页面范围,其中一些值被省略。 如果有大量页面,这有助于在模板中生成合理数量的页面链接。
请求和响应
- 响应头现在存储在 HttpResponse.headers 中。 这可以用来代替
HttpResponse
对象的原始类 dict 接口。 将继续支持这两个接口。 有关详细信息,请参阅 设置标题字段 。 - HttpResponse、SimpleTemplateResponse 和 TemplateResponse 的新
headers
参数允许在实例化时设置响应 headers。
安全
:setting:`SECRET_KEY` 设置现在在第一次访问时检查有效值,而不是在第一次加载设置时。 这样就可以运行不依赖于
SECRET_KEY
的管理命令,而无需提供值。 因此,在不提供有效SECRET_KEY
的情况下调用 configure(),然后继续访问settings.SECRET_KEY
现在将引发 ImproperlyConfigured例外。新的
Signer.sign_object()
和Signer.unsign_object()
方法允许对复杂的数据结构进行签名。 有关更多详细信息,请参阅 保护复杂数据结构 。此外,signing.dumps() 和 loads() 成为 TimestampSigner.sign_object() 和 unsign_object() 的快捷方式。
序列化
- 新的 JSONL 序列化程序允许将 JSON 行格式与 :djadmin:`dumpdata` 和 :djadmin:`loaddata` 一起使用。 这对于填充大型数据库很有用,因为数据是逐行加载到内存中的,而不是一次加载。
模板
- :tfilter:`floatformat` 模板过滤器现在允许使用
g
后缀强制按 :setting:`THOUSAND_SEPARATOR` 对活动语言环境进行分组。 - 使用 缓存模板加载器 缓存的模板现在可以在开发中正确重新加载。
测试
- 分配给 TestCase.setUpTestData() 中的类属性的对象现在对于每个测试方法都是隔离的。 现在需要此类对象支持使用
copy.deepcopy()
创建深拷贝。 分配不支持 [X38X] 的对象已被弃用,并将在 Django 4.1 中删除。 - DiscoverRunner 现在默认启用
faulthandler
。 这可以通过使用test --no-faulthandler
选项禁用。 - DiscoverRunner 和 :djadmin:`test` 管理命令现在可以跟踪时间,包括数据库设置和总运行时间。 这可以通过使用
test --timing
选项启用。 - Client 现在在遵循 307 和 308 重定向时保留请求查询字符串。
- 新的 TestCase.captureOnCommitCallbacks() 方法在列表中捕获传递给 transaction.on_commit() 的回调函数。 这允许您在不使用较慢的 TransactionTestCase 的情况下测试此类回调。
- TransactionTestCase.assertQuerysetEqual() 现在支持与另一个查询集的直接比较,而不是在使用
transform
参数的默认值时仅限于与对象的字符串表示列表进行比较。
公用事业
django.utils.timesince.timesince()
和django.utils.timesince.timeuntil()
函数的新depth
参数允许指定要返回的相邻时间单位的数量。
验证器
- 内置验证器现在在引发的 ValidationError 的
params
参数中包含提供的值。 这允许自定义错误消息使用%(value)s
占位符。 - ValidationError 相等运算符现在忽略
messages
和params
排序。
3.2 中向后不兼容的变化
数据库后端API
本节介绍第三方数据库后端可能需要的更改。
- 新的
DatabaseFeatures.introspected_field_types
属性替换了以下功能:can_introspect_autofield
can_introspect_big_integer_field
can_introspect_binary_field
can_introspect_decimal_field
can_introspect_duration_field
can_introspect_ip_address_field
can_introspect_positive_integer_field
can_introspect_small_integer_field
can_introspect_time_field
introspected_big_auto_field_type
introspected_small_auto_field_type
introspected_boolean_field_type
- 要启用对覆盖索引 (Index.include) 和覆盖唯一约束 (UniqueConstraint.include) 的支持,请将
DatabaseFeatures.supports_covering_indexes
设置为True
。 - 第三方数据库后端必须在
CharField
和TextField
上实现对列数据库排序规则的支持或将DatabaseFeatures.supports_collation_on_charfield
和DatabaseFeatures.supports_collation_on_textfield
设置为False
. 如果不支持非确定性排序规则,请将supports_non_deterministic_collations
设置为False
。 DatabaseOperations.random_function_sql()
被移除以支持新的 Random 数据库功能。DatabaseOperations.date_trunc_sql()
和DatabaseOperations.time_trunc_sql()
现在采用可选的tzname
参数,以便在特定时区进行截断。DatabaseClient.runshell()
现在从DatabaseClient.settings_to_cmd_args_env()
方法获取参数和带有环境变量的可选字典到底层命令行客户端。 第三方数据库后端必须实现DatabaseClient.settings_to_cmd_args_env()
或覆盖DatabaseClient.runshell()
。- 第三方数据库后端必须实现对功能索引的支持(Index.expressions)或将
DatabaseFeatures.supports_expression_indexes
设置为False
。 如果COLLATE
不是CREATE INDEX
语句的一部分,请将DatabaseFeatures.collate_as_index_expression
设置为True
。
django.contrib.admin
- 管理中的分页链接现在是 1-indexed 而不是 0-indexed,即 第一页的查询字符串是
?p=1
而不是?p=0
。 - 新的 admin catch-all 视图将破坏在管理 URL 之后路由并匹配管理 URL 前缀的 URL 模式。 您可以调整您的 URL 顺序,或者,如有必要,将 AdminSite.final_catch_all_view 设置为
False
,禁用全能视图。 有关更多详细信息,请参阅 Django 3.2 中的新增功能 。 - 管理员不再包含缩小的 JavaScript 文件。 如果您需要缩小这些文件,请考虑使用第三方应用程序或外部构建工具。 与管理员一起打包的缩小的供应商 JavaScript 文件(例如 jquery.min.js) 仍然包含在内。
- ModelAdmin.prepopulated_fields 不再去除英文停用词,例如
'a'
或'an'
。
django.contrib.gis
- 删除了对 PostGIS 2.2 的支持。
- Oracle 后端现在克隆多边形(和包含多边形的几何集合),然后重新定向它们并将它们保存到数据库中。 它们不再原地突变。 如果在保存模型后使用多边形,您可能会注意到这一点。
不再支持 PostgreSQL 9.5
对 PostgreSQL 9.5 的上游支持将于 2021 年 2 月结束。 Django 3.2 支持 PostgreSQL 9.6 及更高版本。
不再支持 MySQL 5.6
MySQL 5.6 上游支持的结束时间是 2021 年 4 月。 Django 3.2 支持 MySQL 5.7 及更高版本。
杂项
Django 现在支持非
pytz
时区,例如 Python 3.9+ 的zoneinfo
模块及其向后移植。未记录的
SpatiaLiteOperations.proj4_version()
方法重命名为proj_version()
。slugify() 现在删除前导和尾随的破折号和下划线。
:tfilter:`intcomma` 和 :tfilter:`intword` 模板过滤器不再依赖于 :setting:`USE_L10N` 设置。
支持
argon2-cffi
< 19.1.0 被删除。当禁用国际化 (
USE_I18N = False
) 和启用本地化 (USE_L10N = True
) 时,缓存键不再包含语言。 在此类配置中升级到 Django 3.2 后,对任何先前缓存的值的第一个请求将是缓存未命中。ForeignKey.validate()
现在使用 _base_manager 而不是 _default_manager 来检查相关实例是否存在。当应用程序在
apps.py
子模块中定义 AppConfig 子类时,Django 现在会自动使用此配置,即使它未通过default_app_config
启用。 如果您需要防止这种行为,请在 AppConfig 子类中设置default = False
。 有关更多详细信息,请参阅 Django 3.2 中的新增功能 。现在实例化抽象模型会引发
TypeError
。setup_databases() 的关键字参数现在只有关键字。
未记录的
django.utils.http.limited_parse_qsl()
函数被删除。 请改用urllib.parse.parse_qsl()
。django.test.utils.TestContextDecorator
现在使用addCleanup()
,以便在TestContextDecorator.disable()
之前调用在setUp()
方法中注册的清理。SessionMiddleware
现在在并发请求中销毁会话时引发 SessionInterrupted 异常而不是 SuspiciousOperation。django.db.models.Field 相等运算符现在可以正确区分跨模型继承的字段实例。 此外,现在定义了此类字段的顺序。
如果文件无法锁定,未记录的
django.core.files.locks.lock()
函数现在返回False
,而不是提高BlockingIOError
。当用户电子邮件更改时,密码重置机制现在会使令牌无效。
:djadmin:`makemessages` 命令不再处理使用
makemessages --locale
选项指定的无效语言环境,当它们包含连字符 ('-'
) 时。django.contrib.auth.forms.ReadOnlyPasswordHashField
表单域现在默认为 禁用 。 因此UserChangeForm.clean_password()
不再需要返回初始值。cache.get_many()
、get_or_set()
、has_key()
、incr()
、decr()
、incr_version()
和decr_version()
缓存操作现在可以像处理任何其他值一样正确处理存储在缓存中的None
,而不是表现得好像键不存在一样。由于
python-memcached
的限制,已弃用的MemcachedCache
后端保留了之前的行为。SQLite 支持的最低版本从 3.8.3 增加到 3.9.0。
CookieStorage 现在以 RFC 6265 兼容格式存储消息。 对使用旧格式的 cookie 的支持一直持续到 Django 4.1。
asgiref
的最低支持版本从3.2.10增加到3.3.2。
3.2 中弃用的功能
杂项
- 不推荐使用
copy.deepcopy()
将不支持创建深拷贝的对象分配给 TestCase.setUpTestData() 中的类属性。 - 不推荐在 BaseCommand.requires_system_checks 中使用布尔值。 使用
'__all__'
代替True
,使用[]
(空列表)代替False
。 - EmailValidator 的
whitelist
参数和domain_whitelist
属性已弃用。 使用allowlist
代替whitelist
,使用domain_allowlist
代替domain_whitelist
。 您可能需要在现有迁移中重命名whitelist
。 default_app_config
应用程序配置变量已弃用,因为现在自动发现AppConfig
。 有关更多详细信息,请参阅 Django 3.2 中的新增功能 。- 与字符串值相比,不推荐在
TransactionTestCase.assertQuerysetEqual()
中的查询集上自动调用repr()
。 如果您需要之前的行为,请将transform
显式设置为repr
。 django.core.cache.backends.memcached.MemcachedCache
后端已被弃用,因为python-memcached
存在一些问题并且似乎没有维护。 请改用django.core.cache.backends.memcached.PyMemcacheCache
或django.core.cache.backends.memcached.PyLibMCCache
。django.contrib.messages.storage.cookie.CookieStorage
使用的消息格式与旧版本 Django 生成的格式不同。 对旧格式的支持一直到 Django 4.1。