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
支持¶The new django.core.cache.backends.memcached.PyMemcacheCache
cache backend
allows using the pymemcache library for memcached. pymemcache
3.4.0
or higher is required. For more details, see the documentation on caching
in 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
¶GDALRaster.transform()
方法现在支持 SpatialReference
。DataSource
类现在支持 pathlib.Path
。LayerMapping
类现在支持 pathlib.Path
。django.contrib.postgres
¶ExclusionConstraint.include
属性允许在 PostgreSQL 12+ 上创建覆盖排除约束。ExclusionConstraint.opclasses
attribute allows setting PostgreSQL
operator classes.JSONBAgg.ordering
属性决定了聚合元素的排序。JSONBAgg.distinct
属性决定了聚合的值是否会是唯一的。CreateExtension
操作现在会检查数据库中是否已经存在扩展,如果存在则跳过迁移过程。CreateCollation
和 RemoveCollation
操作允许在 PostgreSQL 上创建和删除排序。参见 使用迁移来管理整理 获取更多细节。ArrayField
的查找现在允许包含表达式的(非嵌套)数组作为右侧。OpClass()
表达式允许在具有自定义运算符类的表达式上创建函数索引。参见 函数索引 获取更多细节。django.contrib.sitemaps
¶Sitemap
属性 alternates
、languages
和 x_default
允许生成网站地图 替换为 你页面的本地化版本。django.contrib.syndication
¶item_comments
钩子允许为每个 feed 项目指定一个评论 URL。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
现在支持指定一个标签列表。在所选标签中注册的系统检查将在执行命令前被检查出错误。在之前的版本中,所有的系统检查或者都不执行,或者都会被执行。Operation.migration_name_fragment
属性允许提供一个文件名片段,该片段将被用来命名只包含该操作的迁移。pathlib
和 os.PathLike
实例中序列化纯路径和具体路径对象。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()
表达式现在会根据其提供的 value
的类型自动将其 output_field
解析为适当的 Field
子类,适用于 bool
、bytes
、float
、int
、str
、datetime.date
、datetime.datetime
、datetime.time
、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()
以及其他表达式现在允许使用变换。详情参见 Expressions can reference transforms。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 进行分组TestCase.setUpTestData()
中分配给类属性的对象现在对每个测试方法都是孤立的。这些对象现在需要支持用 copy.deepcopy()
创建深度拷贝。指定不支持 deepcopy()
的对象已被废弃,并将在 Django 4.1 中被移除。DiscoverRunner
现在默认启用 faulthandler
。这可以通过使用 test --no-faulthandler
选项来禁用。DiscoverRunner
和 test
管理命令现在可以跟踪计时,包括数据库设置和总运行时间。这可以通过使用 test --timing
选项来启用。Client
现在在跟随 307 和 308 重定向时保留了请求的查询字符串。TestCase.captureOnCommitCallbacks()
方法在一个列表中捕获传递给 transaction.on_commit()
的回调函数。这允许你在不使用较慢的 TransactionTestCase
的情况下测试此类回调。TransactionTestCase.assertQuerysetEqual()
now supports direct
comparison against another queryset rather than being restricted to
comparison against a list of string representations of objects when using the
default value for the transform
argument.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
¶?p=1
,而不是 ?p=0
。AdminSite.final_catch_all_view
设置为 False
,禁用全局回退视图。更多细节见 Django 3.2 新特性。ModelAdmin.prepopulated_fields
不再剥离英文停顿词,例如 'a'
或 'an'
。django.contrib.gis
¶对 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()
现在可以删除前面和后面的破折号以及下划线。
The intcomma
and intword
template filters no longer
depend on the USE_L10N
setting.
移除对 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()
所以在 setUp()
方法中注册的清理会在 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。
TestCase.setUpTestData()
中,将不支持用 copy.deepcopy()
创建深度拷贝的对象分配给类属性的做法已被废弃。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月 05, 2023