2019年4月1日
欢迎来到Django 2.2!
这些发行说明涵盖了 new features 以及一些 backwards incompatible changes 从Django 2.1或更早版本升级时,您需要注意。我们已经 begun the deprecation process for some features .
见 如何将Django升级到更新版本 如果正在更新现有项目,则提供指南。
Django 2.2被指定为 long-term support release .它将在发布后至少三年内收到安全更新。对之前的RTS 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)。我们 highly recommend 并且仅官方支持每个系列的最新版本。
新的 CheckConstraint 和 UniqueConstraint 类允许添加自定义数据库约束。使用将约束添加到模型 Meta.constraints 选择权。
django.contrib.admin¶在的列标题中添加了一个css类 TabularInline .
django.contrib.auth¶这个 HttpRequest 现在作为第一个位置参数传递给 RemoteUserBackend.configure_user() 如果它接受它。
django.contrib.gis¶django.contrib.postgres¶新的 BTreeIndex , HashIndex 和 SpGistIndex 类允许创建 B-Tree , hash 和 SP-GiST 数据库中的索引。
BrinIndex 现在有 autosummarize 参数。
新的 search_type 参数 SearchQuery 允许搜索短语或原始表达式。
django.contrib.staticfiles¶添加了与 collectstatic --ignore 选择使模式 /vendor/*.js 可以使用。
为添加了结果流 QuerySet.iterator() 关于SQLite。
新的 View.setup 钩子在调用之前初始化视图属性 dispatch() 。它允许Mixin设置实例属性,以便在子类中重用。
增加了对亚美尼亚语言的支持和翻译。
新的 --force-color 选项强制命令输出着色。
inspectdb 现在在PostgreSQL上为外部表创建模型。
inspectdb --include-views 现在为Oracle和PostgreSQL上的物化视图创建模型。
新的 inspectdb --include-partitions 选项允许为PostgreSQL上的分区表创建模型。在旧版本中,模型是创建子表而不是父表的。
inspectdb 现在反思 DurationField 对于Oracle和PostgreSQL,以及 AutoField 对于SQLite。
关于Oracle, dbshell 被包裹 rlwrap ,如果可用的话。 rlwrap 提供命令历史记录和键盘输入的编辑。
新的 makemigrations --no-header 选项避免在生成的迁移文件中写入头注释。此选项也可用于 squashmigrations .
新的 migrate --plan 选项打印将要执行的迁移操作的列表。
NoneType 现在可以在迁移中序列化。
现在你可以 register custom serializers 用于迁移。
添加了对PostgreSQL运算符类的支持 (Index.opclasses )
添加了对部分索引的支持 (Index.condition )
增加了 NullIf 和 Reverse 数据库函数以及许多 math database functions .
设置新 ignore_conflicts 参数 QuerySet.bulk_create() 到 True 告诉数据库忽略插入唯一性约束或其他检查失败的行的失败。
新的 ExtractIsoYear 函数从中提取ISO-8601周编号年份 DateField 和 DateTimeField 和新的 iso_year 查找允许按ISO-8601周编号年份查询。
新的 QuerySet.bulk_update() 方法允许有效地更新多个模型实例上的特定字段。
当执行单个查询时,django不再总是启动事务,例如 Model.save() , QuerySet.update() 和 Model.delete() . 这通过减少数据库往返次数来提高自动提交的性能。
处理 DISTINCT 聚合添加到 Aggregate 类。添加 allow_distinct = True 作为类属性 Aggregate 子类允许 distinct 要在初始化时指定的关键字参数,以确保仅对的每个不同值调用聚合函数 expressions .
这个 RelatedManager.add() , create() , remove() , set() , get_or_create() 和 update_or_create() 方法现在可以用于与中间模型的多对多关系。新的 through_defaults 参数用于指定新中间模型实例的值。
补充 HttpRequest.headers 允许简单访问请求的头。
现在可以使用包含 forward references 旁路 handle_forward_references=True 到 serializers.deserialize() . 此外, loaddata 自动处理转发引用。
新的 SimpleTestCase.assertURLEqual() 断言检查给定的URL,忽略查询字符串的顺序。 assertRedirects() 使用新断言。
测试 Client 现在支持列表和元组的自动JSON序列化 data 什么时候? content_type='application/json' .
新的 ORACLE_MANAGED_FILES 测试数据库设置允许使用Oracle托管文件(OMF)表空间。
可延迟的数据库约束现在在每个 TestCase 在sqlite 3.20+上测试,就像在支持可延迟约束的其他后端上一样。这些检查并没有为旧版本的sqlite实现,因为它们需要昂贵的表内省。
DiscoverRunner 现在跳过数据库的设置,而不是 referenced by tests .
新的 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() and _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() and _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 is not cached. Where the problem can be detected (Python 3.6 and
later), such usage now raises TypeError: Cannot assign the same
cached_property to two different names ('base' and 'alias').
改为使用:
import operator
class A:
...
alias = property(operator.attrgetter("base"))
Permissions for proxy models 现在使用代理模型的内容类型而不是具体模型的内容类型创建。迁移将在运行时更新现有权限 migrate .
在管理员中,对于具有相同代理模型的代理模型,更改是透明的。 app_label 作为他们的具体模型。但是,在旧版本中,具有代理模型权限的用户 不同的 app_label 它的具体模型无法访问管理中的模型。现在已修复,但您可能希望审核此类代理模型的权限分配 ([add|view|change|delete]_myproxy )在升级之前,确保新的访问是适当的。
最后,必须更新代理模型权限字符串以使用它们自己的权限字符串 app_label . 例如,对于 app.MyProxyModel 继承 other_app.ConcreteModel 更新 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', ...] 什么时候? declaring form media assets .
为了提高可读性, 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() 不能再通过bytestring。
支持 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() 现在提高 TypeError 如果 None 作为要编码的值传递,因为 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 (由守望者取代)。
这个 Avg , StdDev 和 Variance 聚合函数现在返回 Decimal 而不是 float 当输入为 Decimal .
如果没有迁移的应用程序与带有迁移的应用程序有关系,则SQLite上的测试将失败。自从Django1.7中添加了迁移之后,这是一个有记录的限制,但现在它失败得更可靠了。您将看到测试失败,错误如下 no such table: <app_label>_<model> . 这是在几个第三方应用程序中观察到的,这些第三方应用程序在没有迁移的测试中具有模型。必须为此类模型添加迁移。
在中提供一个整 key 的论据 cache.delete() 或 cache.get() 现在提高 ValueError 。
某些语言的复数方程发生了变化,因为合并了Transifex的最新版本。
备注
能力处理 .po Django 2.2.12中添加了包含相同语言的不同复数方程的文件。
Meta.ordering 将不再影响 GROUP BY 查询¶模型的 Meta.ordering 影响 GROUP BY 查询(例如 .annotate().values() )是造成混乱的常见原因。这样的查询现在会发出一个弃用警告,建议添加一个 order_by() 保留当前查询。 Meta.ordering 将在Django 3.1中开始的此类查询中被忽略。
django.utils.timezone.FixedOffset 被否决,赞成 datetime.timezone .
无证件者 QuerySetPaginator 的别名 django.core.paginator.Paginator 被贬低。
这个 FloatRangeField 中的模型和表单字段 django.contrib.postgres 不赞成使用新名称, DecimalRangeField ,以匹配基础 numrange 数据库中使用的数据类型。
这个 FILE_CHARSET 设置已弃用。从Django3.1开始,从磁盘读取的文件必须是UTF-8编码的。
django.contrib.staticfiles.storage.CachedStaticFilesStorage 由于存在难以解决的问题而被弃用。使用 ManifestStaticFilesStorage 或者是第三方云存储。
RemoteUserBackend.configure_user() 现在通过 request 作为第一个位置参数,如果它接受它。对不接受的覆盖的支持将在Django 3.1中删除。
这个 SimpleTestCase.allow_database_queries , TransactionTestCase.multi_db ,以及 TestCase.multi_db 属性被弃用,支持 SimpleTestCase.databases , TransactionTestCase.databases ,以及 TestCase.databases .这些新属性允许声明数据库依赖项,以防止针对非默认数据库的意外查询在测试之间泄露状态。之前的行为 allow_database_queries=True 和 multi_db=True 可以通过设置来实现 databases='__all__' 。
5月 28, 2025