2021 年 4 月 6 日
欢迎来到 Django 3.2 版本!
这些发行说明涵盖了 新功能,以及一些 向后不兼容的变化,当你从 Django 3.1 或更早版本升级时,你需要注意。我们已经 开始了一些功能的废弃过程。
如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。
Django 3.2 被指定为 长期支持发行。它将在发行后至少三年内获得安全更新。对前一个 LTS,即 Django 2.2 的支持将于 2022 年 4 月结束。
Django 3.2 支持 Python 3.6、3.7、3.8、3.9 和 3.10(从 3.2.9 开始)。我们 高度推荐 并且只正式支持每个系列的最新版本。
AppConfig 发现¶大多数可插拔的应用程序在 apps.py 子模块中定义一个 AppConfig 子类。许多人在他们的 __init__.py 中定义了一个 default_app_config 的变量,指向这个类。
当 apps.py 子模块存在并定义了一个 AppConfig 子类时,Django 现在自动使用该配置,所以你可以删除 default_app_config。
default_app_config 使得在 INSTALLED_APPS 中只需声明应用程序的路径(例如 'django.contrib.admin')而不是应用程序配置的路径(例如 'django.contrib.admin.apps.AdminConfig')。它的引入是为了向后兼容前者的风格,目的是将生态系统切换到后者,但这种切换并没有发生。
随着自动发现 AppConfig,default_app_config 不再需要了。因此,它被废弃了。
详见 配置应用程序。
当定义一个模型时,如果模型中没有字段被定义为 primary_key=True,则会添加一个隐式主键。这个隐式主键的类型现在可以通过 DEFAULT_AUTO_FIELD 设置和 AppConfig.default_auto_field 属性来控制。不再需要在所有模型中覆盖主键。
保持历史行为,DEFAULT_AUTO_FIELD 的默认值是 AutoField。从 3.2 开始,新项目在生成时,DEFAULT_AUTO_FIELD 设置为 BigAutoField。另外,新的应用程序生成时,AppConfig.default_auto_field 设置为 BigAutoField。在未来的 Django 版本中,DEFAULT_AUTO_FIELD 的默认值将被改为 BigAutoField。
为了避免将来不需要的迁移,要么明确设置 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)
由于预期默认值的变化,如果你没有明确设置 DEFAULT_AUTO_FIELD,系统检查将提供一个警告。
当改变 DEFAULT_AUTO_FIELD 的值时,目前不能生成现有的自动创建的表的主键的迁移。请参阅 DEFAULT_AUTO_FIELD 文档以了解迁移此类表的详情。
新的 *expressions 的位置参数 Index() 能够在表达式和数据库函数上创建函数索引。例如:
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 将所需的内存从 512KB 推到 100MB。这仍然是相当保守的,但在内存有限的环境中可能会导致问题。如果是这种情况,可以对现有的散列器进行子类化以覆盖默认值。
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¶DataSource 类现在支持 pathlib.Path。
LayerMapping 类现在支持 pathlib.Path。
django.contrib.postgres¶新的 ExclusionConstraint.include 属性允许在 PostgreSQL 12+ 上创建覆盖排除约束。
新的 ExclusionConstraint.opclasses 属性允许设置 PostgreSQL 操作符类。
The new JSONBAgg.ordering attribute determines the ordering of the
aggregated elements.
新的 JSONBAgg.distinct 属性决定了聚合的值是否会是唯一的。
CreateExtension 操作现在会检查数据库中是否已经存在扩展,如果存在则跳过迁移过程。
新的 CreateCollation 和 RemoveCollation 操作允许在 PostgreSQL 上创建和删除排序。参见 使用迁移来管理整理 获取更多细节。
对 ArrayField 的查找现在允许包含表达式的(非嵌套)数组作为右侧。
django.contrib.sitemaps¶新的 Sitemap 属性 alternates、languages 和 x_default 允许生成网站地图 替换为 你页面的本地化版本。
第三方数据库后端现在可以使用新的 DatabaseFeatures.django_test_skips 和 django_test_expected_failures 属性在 Django 测试套件中跳过或标记为预期失败的测试。
新的 no_append_slash() 装饰器允许个别视图从 APPEND_SLASH URL 规范化中排除。
自定义 ExceptionReporter 子类现在可以定义 html_template_path 和 text_template_path 属性来重写用于渲染异常报告的模板。
新的 FileUploadHandler.upload_interrupted() 回调允许处理中断的上传。
formset_factory()、inlineformset_factory() 和 modelformset_factory() 的新 absolute_max 参数允许自定义提供 POST 数据时可实例化的最大表单数量。参见 限制实例化表单的最大数量 以了解更多细节。
formet_factory()、inlineformset_factory() 和 modelformset_factory() 的新参数 can_delete_extra 允许删除额外的表单选项。更多信息请参见 can_delete_extra。
BaseFormSet 现在当管理表单丢失或被篡改时,会报告一个面向用户的错误,而不是引发一个异常。要自定义这个错误信息,请在实例化表单集时,将 error_messages 参数与 'missing_management_form' 键一起传递。
WeekMixin 和 WeekArchiveView 的 week_format 属性现在支持 '%V' ISO 8601 星期格式。
loaddata 现在支持存储在 XZ 档案(.xz)和 LZMA 档案(.lzma)中的固定数据。
dumpdata 现在可以压缩 bz2、gz、lzma 或 xz 格式的数据。
makemigrations 现在可以在没有数据库连接的情况下调用。在这种情况下,会跳过检查是否有一致的迁移历史。
BaseCommand.required_system_checks 现在支持指定一个标签列表。在所选标签中注册的系统检查将在执行命令前被检查出错误。在之前的版本中,所有的系统检查或者都不执行,或者都会被执行。
更新了对 Windows 上彩色终端输出的支持。各种现代终端环境被自动检测到,在其他情况下启用支持的选项也被改进。更多细节见 语法着色。
新的 Operation.migration_name_fragment 属性允许提供一个文件名片段,该片段将被用来命名只包含该操作的迁移。
迁移现在支持从 pathlib 和 os.PathLike 实例中序列化纯路径和具体路径对象。
The new no_key parameter for QuerySet.select_for_update(),
supported on PostgreSQL, allows acquiring weaker locks that don't block the
creation of rows that reference locked rows through a foreign key.
When() 表达式现在允许使用 condition 参数与 lookups。
新的 Index.include 和 UniqueConstraint.include 属性允许在 PostgreSQL 11+ 上创建覆盖索引和覆盖唯一约束。
新的 UniqueConstraint.opclasses 属性允许设置 PostgreSQL 操作符类。
QuerySet.update() 方法现在尊重 MySQL 和 MariaDB 的 order_by() 子句。
FilteredRelation() 现在支持嵌套关系。
The of argument of QuerySet.select_for_update() is now allowed
on MySQL 8.0.1+.
Value() expression now
automatically resolves its output_field to the appropriate
Field subclass based on the type of
its provided value for bool, bytes,
float, int, str,
datetime.date, datetime.datetime,
datetime.time, datetime.timedelta,
decimal.Decimal, and uuid.UUID instances. As a
consequence, resolving an output_field for database functions and
combined expressions may now crash with mixed types when using Value().
You will need to explicitly set the output_field in such cases.
新的 QuerySet.alias() 方法允许为表达式创建可重复使用的别名,这些表达式不需要被选择,但可用于过滤、排序,或作为复杂表达式的一部分。
新的 Collate 函数允许通过指定的数据库排列方式进行过滤和排序。
The field_name argument of QuerySet.in_bulk() now accepts
distinct fields if there's only one field specified in
QuerySet.distinct().
TruncDate 和 TruncTime 数据库函数的新 tzinfo 参数允许截断特定时区的数据时间。
添加了 Random 数据库函数。
聚合函数、F()、OuterRef() 以及其他表达式现在允许使用变换。详情参见 表达式可以引用变换。
atomic() 的新参数 durable 保证在原子块中所做的更改将被提交,如果该块退出时没有错误。嵌套的原子块被标记为耐用,将引发一个 RuntimeError。
添加了 JSONObject 数据库函数。
新的 django.core.paginator.Paginator.get_elided_page_range() 方法允许生成一个页面范围,其中的一些值被删除。如果有大量的页面,这对在模板中生成合理数量的页面链接很有帮助。
响应头信息现在被存储在 HttpResponse.headers 中。这可以代替原来的 HttpResponse 对象的类似字典的接口。这两个接口将继续被支持。详情见 设置头字段。
HttpResponse、SimpleTemplateResponse 以及 TemplateResponse 的新 headers 参数允许在实例化时设置响应的 headers。
SECRET_KEY 配置现在是在第一次访问时检查有效值,而不是在第一次加载设置时。这使得运行不依赖 SECRET_KEY 的管理命令不需要提供一个值。因此,在没有提供有效的 SECRET_KEY 的情况下调用 configure(),然后继续访问 settings.SECRET_KEY 现在会引发一个 ImproperlyConfigured 异常。
新的 Signer.sign_object() 和 Signer.unsign_object() 方法允许签署复杂数据结构。更多细节见 保护复杂的数据结构。
另外, signing.dumps() 和 load() 成为 TimestampSigner.sign_object() 和 unsign_object() 的快捷方式。
Signal.send_robust() 现在会记录异常。
floatformat 模板过滤器现在允许使用 g 后缀来强制按 THOUSAND_SEPARATOR 对活动 locale 进行分组
用 缓存的模板加载器 缓存的模板现在可以在开发模式中正确地重新加载。
Objects assigned to class attributes in TestCase.setUpTestData() are
now isolated for each test method. Such objects are now required to support
creating deep copies with copy.deepcopy(). Assigning objects which
don't support deepcopy() is deprecated and will be removed in Django 4.1.
DiscoverRunner now enables
faulthandler by default. This can be disabled by using the
test --no-faulthandler option.
DiscoverRunner 和 test 管理命令现在可以跟踪计时,包括数据库设置和总运行时间。这可以通过使用 test --timing 选项来启用。
Client 现在在跟随 307 和 308 重定向时保留了请求的查询字符串。
新的 TestCase.captureOnCommitCallbacks() 方法在一个列表中捕获传递给 transaction.on_commit() 的回调函数。这允许你在不使用较慢的 TransactionTestCase 的情况下测试此类回调。
TransactionTestCase.assertQuerysetEqual() 现在支持直接与另一个查询集进行比较,而不仅仅是在使用默认值的情况下与对象的字符串表示列表进行比较时。
django.utils.timesince.timesince() 和 django.utils.timesince.timeuntil() 函数的新 depth 参数允许指定要返回的相邻时间单位的数量。
内置的验证器现在包括提供的值在提出的 ValidationError 的 params 参数。这允许自定义错误信息使用 %(value)s 占位符。
ValidationError 相等运算符现在忽略了 messages 和 params 的排序。
本节介绍了第三方数据库后端可能需要的更改。
新的 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 开头索引,而不是 0 开头索引,即第一页的查询字符串是 ?p=1,而不是 ?p=0。
新的管理全局回退视图将打破在管理 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 的上游支持在 2021 年 2 月结束。Django 3.2 支持 PostgreSQL 9.6 及以上版本。
对 MySQL 5.6 的上游支持在 2021 年 4 月结束。Django 3.2 支持 MySQL 5.7 及以上版本。
Django 现在支持非 pytz 时区,例如 Python 3.9+ 的 zoneinfo 模块及其向后移植版本。
未记录的 SpatiaLiteOperations.proj4_version() 方法改名为 proj_version()。
slugify() 现在可以删除前面和后面的破折号以及下划线。
移除对 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 now uses
addCleanup() so that cleanups registered in the
setUp() method are called before
TestContextDecorator.disable().
当一个会话在并发请求中被销毁时,SessionMiddleware 现在会引发 SessionInterrupted 异常,而不是 SuspiciousOperation。
django.db.models.Field 相等运算符现在可以正确区分跨模型的继承字段实例。此外,此类字段的排序现在也被定义了。
未记录的 django.core.files.locks.lock() 函数现在在文件不能被锁定时返回 False,而不是引发 BlockingIOError。
密码重置机制现在在用户电子邮件改变时使令牌无效。
makemessages 命令不再处理使用 makemessages --locale 选项指定的无效 locale,如果它们包含连字符('-')。
django.contrib.auth.forms.ReadOnlyPasswordHashField 表单字段现在默认为 disabled。因此 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。
Assigning objects which don't support creating deep copies with
copy.deepcopy() to class attributes in
TestCase.setUpTestData() is deprecated.
在 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。
12月 22, 2025