2019 年 4 月 1 日
欢迎使用 Django 2.2 !
这些发布说明涵盖了 新功能,以及在从 Django 2.1 或更早版本升级时需要注意的一些 向后不兼容的更改。我们已经 开始了一些功能的弃用过程。
如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。
Django 2.2 被指定为 长期支持版本。它将在发布后至少三年内接收安全更新。对于之前的 LTS 版本 Django 1.11,支持将在 2020 年 4 月结束。
Django 2.2 支持 Python 3.5、3.6、3.7、3.8(从 2.2.8 版开始),以及 3.9(从 2.2.17 版开始)。我们 强烈建议 并只官方支持每个系列的最新版本。
新的 CheckConstraint 和 UniqueConstraint 类允许添加自定义数据库约束。约束可以使用 Meta.constraints 选项添加到模型中。
django.contrib.admin¶为 TabularInline 的列标题添加了一个 CSS 类。
django.contrib.auth¶如果接受,现在将 HttpRequest 作为 RemoteUserBackend.configure_user() 的第一个位置参数传递。
django.contrib.gis¶django.contrib.postgres¶新的 BTreeIndex、HashIndex 和 SpGistIndex 类允许在数据库中创建 B-Tree、hash 和 SP-GiST 索引。
BrinIndex 现在具有 autosummarize 参数。
SearchQuery 的新参数 search_type 允许搜索短语或原始表达式。
django.contrib.staticfiles¶在 collectstatic --ignore 选项中添加了路径匹配功能,以便可以使用像 /vendor/*.js 这样的模式。
在 SQLite 上为 QuerySet.iterator() 添加了结果流式传输功能。
新的 View.setup 钩子在调用 dispatch() 之前初始化视图属性。它允许 mixins 设置实例属性,以便在子类中重用。
增加了对亚美尼亚语的支持和翻译。
新的 --force-color 选项强制对命令输出进行着色。
inspectdb 现在会为 PostgreSQL 上的外部表创建模型。
inspectdb --include-views 现在会为 Oracle 和 PostgreSQL 上的物化视图创建模型。
新的 inspectdb --include-partitions 选项允许在 PostgreSQL 上为分区表创建模型。在旧版本中,模型是在子表而不是父表中创建的。
inspectdb 现在可以为 Oracle 和 PostgreSQL 自动检测 DurationField,以及为 SQLite 检测 AutoField。
在 Oracle 上,如果可用,dbshell 会使用 rlwrap 包装。rlwrap 提供了命令历史记录和键盘输入的编辑功能。
新的 makemigrations --no-header 选项可以避免在生成的迁移文件中写入头部注释。这个选项也适用于 squashmigrations。
新的 migrate --plan 选项会打印将执行的迁移操作列表。
NoneType 现在可以在迁移中序列化。
现在可以为迁移 注册自定义序列化程序。
添加了对 PostgreSQL 运算符类 (Index.opclasses) 的支持。
添加了对部分索引 (Index.condition) 的支持。
将 QuerySet.bulk_create() 的新参数 ignore_conflicts 设置为 True 会告诉数据库忽略插入失败的行,即违反唯一性约束或其他检查的行。
新的 ExtractIsoYear 函数从 DateField 和 DateTimeField 中提取 ISO-8601 周编号年,新的 iso_year 查询允许按 ISO-8601 周编号年进行查询。
新的 QuerySet.bulk_update() 方法允许高效地更新多个模型实例上的特定字段。
Django 不再总是在执行单个查询时启动事务,例如 Model.save(), QuerySet.update() 和 Model.delete()。这通过减少数据库往返次数来提高自动提交的性能。
对于 Aggregate 类,增加了 DISTINCT 聚合的处理。在 Aggregate 子类上添加 allow_distinct = True 作为类属性,允许在初始化时指定一个 distinct 关键字参数,以确保聚合函数仅对 expressions 的每个不同值调用一次。
现在允许在具有中间模型的多对多关系上使用 RelatedManager.add()、create()、remove()、set()、get_or_create() 和 update_or_create() 方法。新的 through_defaults 参数用于指定新中间模型实例的值。
添加了 HttpRequest.headers,以便简单访问请求的头部信息。
新的 SimpleTestCase.assertURLEqual() 断言检查给定的 URL,忽略查询字符串的顺序。assertRedirects() 使用了这个新的断言。
现在,测试 Client 在 content_type='application/json' 时支持自动对列表和元组 data 进行 JSON 序列化。
新的 ORACLE_MANAGED_FILES 测试数据库设置允许使用 Oracle 管理文件 (OMF) 表空间。
可延迟的数据库约束现在在 SQLite 3.20+ 上的每个 TestCase 测试结束时进行检查,就像其他支持可延迟约束的后端一样。对于较旧版本的 SQLite,这些检查没有实现,因为在那里需要昂贵的表内省。
DiscoverRunner 现在会跳过未被 测试引用 的数据库的设置。
新的 ResolverMatch.route 属性存储匹配的 URL 模式的路由。
MaxValueValidator、MinValueValidator、MinLengthValidator 和 MaxLengthValidator 现在接受可调用的 limit_value。
本节介绍了第三方数据库后端可能需要的更改。
第三方数据库后端必须实现对表检查约束的支持,或将 DatabaseFeatures.supports_table_check_constraints 设置为 False。
第三方数据库后端必须实现在插入时忽略约束或唯一性错误的支持,或将 DatabaseFeatures.supports_ignore_conflicts 设置为 False。
第三方数据库后端必须实现对 DurationField 的内省,或将 DatabaseFeatures.can_introspect_duration_field 设置为 False。
DatabaseFeatures.uses_savepoints 现在默认为 True。
第三方数据库后端必须实现对部分索引的支持,或将 DatabaseFeatures.supports_partial_indexes 设置为 False。
移除了 DatabaseIntrospection.table_name_converter() 和 column_name_converter()。第三方数据库后端可能需要代替实现 DatabaseIntrospection.identifier_converter()。在这种情况下,DatabaseIntrospection.get_constraints() 返回的约束名称必须通过 identifier_converter() 进行规范化。
索引的 SQL 生成从 Index 移动到 SchemaEditor,并添加了以下 SchemaEditor 方法:
_create_primary_key_sql() 和 _delete_primary_key_sql()
_delete_index_sql() (与 _create_index_sql() 配对使用)
_delete_unique_sql (与 _create_unique_sql() 配对使用)
_delete_fk_sql() (与 _create_fk_sql() 配对使用)
_create_check_sql() 和 _delete_check_sql()
移除了 DatabaseWrapper.__init__() 的第三个参数 allow_thread_sharing。
ModelAdmin 类中收集管理操作¶例如,在较旧版本的 Django 中:
from django.contrib import admin
class BaseAdmin(admin.ModelAdmin):
actions = ["a"]
class SubAdmin(BaseAdmin):
actions = ["b"]
SubAdmin 将具有操作 'a' 和 'b'。
现在,actions 遵循标准的 Python 继承。要获得与以前相同的结果:
class SubAdmin(BaseAdmin):
actions = BaseAdmin.actions + ["b"]
django.contrib.gis¶支持 GDAL 1.9 和 1.10 的功能已被移除。
TransactionTestCase 序列化数据加载¶现在,在 TransactionTestCase 的测试结束后,即在数据库刷新之后加载初始数据迁移。在旧版本中,这些数据在测试开始时加载,但这会阻止 test --keepdb 选项正常工作(整个测试套件结束后数据库为空)。除非您已自定义了 TransactionTestCase 的内部,否则这个变化不应影响您的测试。
sqlparse 是必需的依赖项¶为了简化 Django 数据库处理的几个部分,现在 sqlparse 0.2.2+ 是一个必需的依赖项。它会随着 Django 自动安装。
cached_property 别名¶在以下用法中:
from django.utils.functional import cached_property
class A:
@cached_property
def base(self):
return ...
alias = base
alias 不会被缓存。在可以检测到问题的情况下(Python 3.6 及更高版本),此类用法现在会引发 TypeError: Cannot assign the same cached_property to two different names ('base' and 'alias')。
请改用以下方式:
import operator
class A:
...
alias = property(operator.attrgetter("base"))
代理模型的权限 现在使用代理模型的内容类型而不是具体模型的内容类型来创建。在运行 migrate 时,迁移将更新现有的权限。
在管理界面中,对于与其具体模型具有相同的 app_label 的代理模型,这个变化是透明的。然而,在旧版本中,对于具体模型具有不同 app_label 的代理模型的权限的用户不能访问管理中的模型。现在这个问题已经修复,但在升级之前,您可能希望审查这些代理模型的权限分配([add|view|change|delete]_myproxy),以确保新的访问是合适的。
最后,代理模型的权限字符串必须更新以使用它们自己的 app_label。例如,对于继承自 other_app.ConcreteModel 的 app.MyProxyModel,请将 user.has_perm('other_app.add_myproxymodel') 更新为 user.has_perm('app.add_myproxymodel')。
Media 资源¶现在,表单 Media 资源使用拓扑排序算法进行合并,因为旧的成对合并算法对某些情况不足够。不包含其依赖项的 CSS 和 JavaScript 文件现在可能会被错误地排序(而旧算法恰好由于巧合而产生了正确的结果)。
请审查所有的 Media 类以查找任何缺失的依赖项。例如,依赖于 django.jQuery 的小部件在 声明表单媒体资源 时必须指定 js=['admin/js/jquery.init.js', ...]。
为了提高可读性,UUIDField 表单字段现在会显示带有破折号的值,例如 550e8400-e29b-41d4-a716-446655440000,而不是 550e8400e29b41d4a716446655440000。
在 SQLite 上,PositiveIntegerField 和 PositiveSmallIntegerField 现在包含一个检查约束,以防止在数据库中出现负值。如果您有现有的无效数据并运行重新创建表的迁移,您将看到 CHECK constraint failed。
为了与 WSGI 服务器保持一致,测试客户端现在将 Content-Length 头设置为字符串而不是整数。
django.utils.text.slugify() 的返回值不再标记为 HTML 安全。
urlizetrunc、truncatechars、truncatechars_html、truncatewords 和 truncatewords_html 模板过滤器使用的默认截断字符现在是真正的省略号字符(…)而不是 3 个点。您可能需要调整一些测试输出的比较。
不再支持在模板文件系统加载器中使用字节串路径。
django.utils.http.urlsafe_base64_encode() 现在返回一个字符串而不是字节字符串,并且 django.utils.http.urlsafe_base64_decode() 可能不再接受字节字符串作为参数。
不再支持 cx_Oracle 版本低于 6.0。
mysqlclient 的最低支持版本从 1.3.7 增加到 1.3.13。
SQLite 的最低支持版本从 3.7.15 提高到 3.8.3 。
为了提供更语义化的查询数据,NullBooleanSelect 现在呈现 <option> 的值为 unknown、true 和 false,而不是 1、2 和 3。为了向后兼容,旧值仍然被接受为数据。
Group.name 的 max_length 从 80 增加到 150 个字符。
现在在运行于 SQLite 3.20+ 上的测试中,违反可延迟数据库约束的行为将报错,就像其他支持此类约束的后端一样。
为了捕获使用错误,测试 Client 和 django.utils.http.urlencode() 现在如果传递 None 作为要编码的值会引发 TypeError,因为 None 不能编码为 GET 和 POST 数据。要么传递空字符串,要么省略值。
现在,ping_google 管理命令默认使用 https 而不是 http 作为站点地图的 URL。如果你的站点使用 http,请使用新的 ping_google --sitemap-uses-http 选项。如果你使用 django.contrib.sitemaps.ping_google 函数,请将新的 sitemap_uses_https 参数设置为 False。
runserver 不再支持 pyinotify (已被 Watchman 替代)。
当输入是 Decimal 时, Avg、StdDev 和 Variance 聚合函数现在返回 Decimal 而不是 float。
如果没有迁移的应用与具有迁移的应用有关系,那么在 SQLite 上的测试将失败。这自从 Django 1.7 添加迁移以来一直是一个已记录的限制,但现在它失败得更可靠。您将看到类似于 no such table: <app_label>_<model> 的错误导致测试失败。这在一些具有测试中没有迁移的模型的第三方应用中观察到。您必须为这些模型添加迁移。
在 cache.delete() 或 cache.get() 的 key 参数中提供整数现在会引发 ValueError。
由于已纳入 Transifex 的最新版本,某些语言的复数规则方程式已被更改。
Note
在 Django 2.2.12 中添加了处理同一语言的 .po 文件中包含不同复数方程的能力。
Meta.ordering 将不再影响 GROUP BY 查询。¶模型的 Meta.ordering 影响 GROUP BY 查询(例如 .annotate().values())是常见的引发混淆的原因。现在,这种查询会发出一个弃用警告,建议添加一个 order_by() 以保留当前查询。从 Django 3.1 开始,在这种查询中将忽略 Meta.ordering。
django.utils.timezone.FixedOffset 已被弃用,建议使用 datetime.timezone。
未记录的 QuerySetPaginator 别名 django.core.paginator.Paginator 已被弃用。
django.contrib.postgres 中的 FloatRangeField 模型和表单字段已被弃用,推荐使用新名称 DecimalRangeField,以匹配数据库中使用的 numrange 数据类型。
FILE_CHARSET 设置已被弃用。从 Django 3.1 开始,从磁盘读取的文件必须是 UTF-8 编码的。
django.contrib.staticfiles.storage.CachedStaticFilesStorage 已被弃用,因为它存在无法解决的问题。请改用 ManifestStaticFilesStorage 或第三方云存储。
现在,RemoteUserBackend.configure_user() 方法的第一个位置参数是 request,如果该方法接受它的话。不支持不接受 request 参数的覆盖方法,将在 Django 3.1 中移除。
SimpleTestCase.allow_database_queries、TransactionTestCase.multi_db 和 TestCase.multi_db 属性已被弃用,推荐使用 SimpleTestCase.databases、TransactionTestCase.databases 和 TestCase.databases。这些新属性允许声明数据库依赖关系,以防止非默认数据库的意外查询在测试之间泄漏状态。以前的行为可以通过设置 databases='__all__' 来实现,即 allow_database_queries=True 和 multi_db=True。
8月 13, 2025