Django 3.0 发行说明 — Django 文档
Django 3.0 发行说明
2019 年 12 月 2 日
欢迎来到 Django 3.0!
这些发行说明涵盖了 新功能 ,以及从 Django 2.2 或更早版本升级时您需要注意的一些 向后不兼容更改 。 我们已经 删除了一些已达到弃用周期结束的功能 ,并且我们已经 开始了一些功能 的弃用过程。
如果您要更新现有项目,请参阅 将 Django 升级到更新版本 指南。
Python兼容性
Django 3.0 支持 Python 3.6、3.7、3.8 和 3.9(从 3.0.11 开始)。 我们【X3X】强烈推荐【X23X】,官方只支持各系列的最新版本。
Django 2.2.x 系列是最后一个支持 Python 3.5 的。
对旧版本 Django 的第三方库支持
在 Django 3.0 发布之后,我们建议第三方应用程序作者放弃对 Django 2.2 之前的所有版本的支持。 那时,您应该能够使用 python -Wd
运行包的测试,以便出现弃用警告。 修复弃用警告后,您的应用程序应该与 Django 3.0 兼容。
Django 3.0 中的新功能
ASGI 支持
Django 3.0 通过提供对作为 ASGI 应用程序运行的支持,开始了我们使 Django 完全具有异步能力的旅程。
这是我们现有 WSGI 支持的补充。 Django 打算在可预见的未来支持两者。 但是,异步功能仅适用于在 ASGI 下运行的应用程序。
在此阶段异步支持仅适用于外部 ASGI 应用程序。 在内部,一切都保持同步。 异步中间件、视图等。 尚不支持。 但是,您可以在 Django 的应用程序周围使用 ASGI 中间件,允许您将 Django 与其他 ASGI 框架结合起来。
除非您想开始试验异步代码,否则无需切换您的应用程序,但如果您想了解更多信息,我们有 关于使用 ASGI 进行部署的文档。
请注意,作为此更改的副作用,Django 现在知道异步事件循环,并且会阻止您从异步上下文调用标记为“异步不安全”的代码(例如 ORM 操作)。 如果您之前通过异步代码使用 Django,则可能会在您操作不当时触发。 如果您看到 SynchronousOnlyOperation
错误,请仔细检查您的代码并将所有数据库操作移至同步子线程中。
模型字段选择的枚举
自定义枚举类型 TextChoices
、IntegerChoices
和 Choices
现在可用作定义 Field.choices 的一种方式。 TextChoices
和 IntegerChoices
类型用于文本和整数字段。 Choices
类允许为其他具体数据类型定义兼容的枚举。 这些自定义枚举类型支持人类可读的标签,可以通过枚举或其成员上的属性进行翻译和访问。 有关更多详细信息和示例,请参阅 枚举类型 。
小功能
django.contrib.admin
- 添加了对 ModelAdmin.list_display 中属性的
admin_order_field
属性的支持。 - 新的 ModelAdmin.get_inlines() 方法允许根据请求或模型实例指定内联。
- Select2 库从版本 4.0.3 升级到 4.0.7。
- jQuery 从 3.3.1 版本升级到 3.4.1。
django.contrib.auth
- PasswordResetConfirmView 中的新
reset_url_token
属性允许指定作为密码重置 URL 组件显示的令牌参数。 - 添加了 BaseBackend 类以简化身份验证后端的自定义。
- 添加了 get_user_permissions() 方法来镜像现有的 get_group_permissions() 方法。
- 为 django.contrib.auth.forms 中用户名、电子邮件和密码字段的小部件添加了 HTML
autocomplete
属性,以便更好地与浏览器密码管理器交互。 - :djadmin:`createsuperuser` 现在回退到密码和必填字段的环境变量,当在非交互模式下没有提供相应的命令行参数时。
- REQUIRED_FIELDS 现在支持 [X38X]ManyToManyField。
- 新的 UserManager.with_perm() 方法返回具有指定权限的用户。
- PBKDF2 密码哈希器的默认迭代计数从 150,000 增加到 180,000。
django.contrib.gis
- 允许 MySQL 空间查找函数对真实几何图形进行操作。 以前的支持仅限于边界框。
- 添加了 PostGIS 支持的 GeometryDistance 函数。
- 在距离中添加了对
furlong
单元的支持。 - :setting:`GEOIP_PATH` 设置现在支持
pathlib.Path
。 - GeoIP2 类现在接受
pathlib.Path
path
。
django.contrib.postgres
- 新的 RangeOperators 有助于避免 SQL 运算符中的拼写错误,这些运算符可与 RangeField 一起使用。
- 新的 RangeBoundary 表达式表示范围边界。
- 新的 AddIndexConcurrently 和 RemoveIndexConcurrently 类允许在 PostgreSQL 上创建和删除索引
CONCURRENTLY
。
国际化
- 添加了 :setting:`LANGUAGE_COOKIE_HTTPONLY`、:setting:`LANGUAGE_COOKIE_SAMESITE` 和 :setting:`LANGUAGE_COOKIE_SECURE` 设置以设置 [X113X] 设置 [X113X] ]、
SameSite
和Secure
语言 cookie 标志。 这些设置的默认值保留了以前的行为。 - 添加了对乌兹别克语的支持和翻译。
日志记录
- AdminEmailHandler 的新
reporter_class
参数允许提供django.views.debug.ExceptionReporter
子类来自定义发送到站点 的回溯文本:setting:`ADMINS` 当 ]:setting:`DEBUG` 是False
。
管理命令
- 新的
compilemessages --ignore
选项允许在搜索要编译的.po
文件时忽略特定目录。 showmigrations --list
现在显示--verbosity
为 2 及以上时应用的日期时间。- 在 PostgreSQL 上,:djadmin:`dbshell` 现在支持客户端 TLS 证书。
- :djadmin:`inspectdb` 现在在外键具有唯一或主键约束时内省 OneToOneField。
- 新的
--skip-checks
选项在运行命令之前跳过正在运行的系统检查。 startapp --template
和startproject --template
选项现在支持存储在 XZ 档案(.tar.xz
、.txz
)和 LZMA 档案(.tar.lzma
、.tlz
)。
型号
新增 Sign 数据库功能。
Trunc 数据库函数的新
is_dst
参数决定了对不存在和不明确的日期时间的处理。connection.queries
现在在 PostgreSQL 上显示COPY … TO
语句。FilePathField 现在接受
path
的可调用对象。允许自引用的对称中间表 ManyToManyField。
CheckConstraint、UniqueConstraint 和 Index 的
name
属性现在支持使用'%(app_label)s'
和 [ X170X] 占位符。新的 Field.descriptor_class 属性允许模型字段通过覆盖它们的 描述符 来自定义获取和设置行为。
添加了 SmallAutoField,它的作用与 AutoField 非常相似,只是它只允许在特定(依赖于数据库)限制下的值。 从
1
到32767
的值在 Django 支持的所有数据库中都是安全的。AutoField、BigAutoField 和 SmallAutoField 现在分别继承自
IntegerField
、BigIntegerField
和SmallIntegerField
。 系统检查和验证器现在也可以正确继承。FileField.upload_to 现在支持
pathlib.Path
。CheckConstraint 现在支持 MySQL 8.0.16+。
django.db.backends.base.BaseDatabaseFeatures
的新allows_group_by_selected_pks_on_model()
方法允许优化GROUP BY
子句以仅需要选定模型的主键。 默认情况下,它仅支持 PostgreSQL 上的托管模型。要为非托管模型启用
GROUP BY
仅主键优化,您必须子类化 PostgreSQL 数据库引擎,根据需要覆盖特征类allows_group_by_selected_pks_on_model()
方法。 有关示例,请参阅 对内置数据库后端进行子类化 。
请求和响应
- 允许使用
memoryview
内容初始化 HttpResponse。 - 例如,用于 Django 模板,HttpRequest.headers 现在允许使用下划线查找(例如
user_agent
) 代替连字符。
安全
- :setting:`X_FRAME_OPTIONS` 现在默认为
'DENY'
。 在旧版本中,:setting:`X_FRAME_OPTIONS` 设置默认为'SAMEORIGIN'
。 如果您的站点使用自身的框架,则需要明确设置X_FRAME_OPTIONS = 'SAMEORIGIN'
以使其继续工作。 - :setting:`SECURE_CONTENT_TYPE_NOSNIFF` 现在默认为
True
。 启用此功能后,SecurityMiddleware 在所有尚未拥有的响应上设置 X-Content-Type-Options: nosniff 标头。 - SecurityMiddleware 现在可以发送 Referrer-Policy 标头。
测试
- 新的测试 Client 参数
raise_request_exception
允许控制请求期间引发的异常是否也应在测试中引发。 为了向后兼容,该值默认为True
。 如果是False
并且发生了异常,测试客户端将返回一个带有属性 exc_info 的 500 响应,一个提供发生异常信息的元组。 - 可以使用新的
test -k
选项通过测试名称模式选择要运行的测试和测试用例。 - assertHTMLEqual() 使用的 HTML 比较现在将引用相同字符的文本、字符引用和实体引用视为等效的。
- Django 测试运行器现在支持在支持的浏览器上进行硒测试的无头模式。 添加
--headless
选项以启用此模式。 - Django 测试运行器现在支持 [X32X] 和
--start-after
选项来运行从特定顶级模块开始的测试。 - Django 测试运行器现在支持 [X34X] 选项,以在每个错误或失败时生成调试器。
3.0 中向后不兼容的变化
Model.save() 为主键提供默认值时
Model.save() 保存新的 Model
实例时不再尝试查找行并提供主键的默认值,并且始终执行单个 INSERT
] 询问。 在较旧的 Django 版本中,Model.save()
根据行是否存在执行 INSERT
或 UPDATE
。
这使得调用 Model.save()
的同时提供一个默认主键值,相当于将 force_insert=True 传递给模型的 save()
。 尝试使用新的 Model
实例更新现有行将导致 IntegrityError
。
为了更新特定主键值的现有模型,请改用 update_or_create() 方法或 QuerySet.filter(pk=…).update(…)
。 例如:
>>> MyModel.objects.update_or_create(pk=existing_pk, defaults={'name': 'new name'})
>>> MyModel.objects.filter(pk=existing_pk).update(name='new name')
数据库后端API
本节介绍第三方数据库后端可能需要的更改。
DatabaseIntrospection.get_geometry_type()
的第二个参数现在是行描述而不是列名。DatabaseIntrospection.get_field_type()
可能不再返回元组。- 如果数据库可以在添加字段的同一个SQL语句中创建外键,则用相应的SQL添加
SchemaEditor.sql_create_column_inline_fk
; 否则,设置DatabaseFeatures.can_create_inline_fk = False
。 DatabaseFeatures.can_return_id_from_insert
和can_return_ids_from_bulk_insert
重命名为can_return_columns_from_insert
和can_return_rows_from_bulk_insert
。- 使用
datetime.timedelta
实例创建时,数据库函数现在可以处理datetime.timezone
格式(例如timezone(timedelta(hours=5))
,将输出'UTC+05:00'
)。 在datetime_cast_date_sql()
、datetime_extract_sql()
等中准备 DateTimeField 时,第三方后端应处理此格式。 AutoField
、BigAutoField
和SmallAutoField
的条目被添加到DatabaseOperations.integer_field_ranges
以支持这些字段类型的整数范围验证器。 第三方后端可能需要自定义默认条目。DatabaseOperations.fetch_returned_insert_id()
被fetch_returned_insert_columns()
替换,后者返回由INSERT … RETURNING
语句返回的值列表,而不是单个值。DatabaseOperations.return_insert_id()
被接受fields
参数的return_insert_columns()
替换,该参数是插入后要返回的可迭代字段。 通常这只是自动生成的主键。
django.contrib.admin
- 管理员的模型历史更改消息现在更喜欢更具可读性的字段标签而不是字段名称。
django.contrib.gis
- 删除了对 PostGIS 2.1 的支持。
- 删除了对 SpatiaLite 4.1 和 4.2 的支持。
- 删除了对 GDAL 1.11 和 GEOS 3.4 的支持。
不再支持 PostgreSQL 9.4
对 PostgreSQL 9.4 的上游支持将于 2019 年 12 月结束。 Django 3.0 支持 PostgreSQL 9.5 及更高版本。
不再支持 Oracle 12.1
对 Oracle 12.1 的上游支持将于 2021 年 7 月结束。 Django 2.2 将支持到 2022 年 4 月。 Django 3.0 正式支持 Oracle 12.2 和 18c。
删除了私有 Python 2 兼容性 API
虽然 Django 2.0 中删除了 Python 2 支持,但一些私有 API 并未从 Django 中删除,以便第三方应用程序可以继续使用它们,直到 Python 2 生命周期结束。
由于我们希望应用程序在添加对 Django 3.0 的支持时会降低 Python 2 兼容性,因此我们此时将删除这些 API。
django.test.utils.str_prefix()
- 字符串在 Python 3 中没有 'u' 前缀。django.test.utils.patch_logger()
- 改用unittest.TestCase.assertLogs()
。django.utils.lru_cache.lru_cache()
-functools.lru_cache()
的别名。django.utils.decorators.available_attrs()
- 此函数返回functools.WRAPPER_ASSIGNMENTS
。django.utils.decorators.ContextDecorator
-contextlib.ContextDecorator
的别名。django.utils._os.abspathu()
-os.path.abspath()
的别名。django.utils._os.upath()
和npath()
- 这些函数在 Python 3 上没有任何作用。django.utils.six
- 删除此供应商库的使用或切换到 six。django.utils.encoding.python_2_unicode_compatible()
-six.python_2_unicode_compatible()
的别名。django.utils.functional.curry()
- 使用functools.partial()
或functools.partialmethod
。 参见 :commit:`5b1c389603a353625ae1603`。django.utils.safestring.SafeBytes
- 自 Django 2.0 起未使用。
FILE_UPLOAD_PERMISSIONS 设置的新默认值
在旧版本中,:setting:`FILE_UPLOAD_PERMISSIONS` 设置默认为 None
。 使用默认的 :setting:`FILE_UPLOAD_HANDLERS`,这会导致上传的文件根据其大小和使用的上传处理程序具有不同的权限。
FILE_UPLOAD_PERMISSIONS
现在默认为 0o644
以避免这种不一致。
安全设置的新默认值
为了让 Django 项目默认更安全,一些安全设置现在有更安全的默认值:
- :setting:`X_FRAME_OPTIONS` 现在默认为
'DENY'
。 - :setting:`SECURE_CONTENT_TYPE_NOSNIFF` 现在默认为
True
。
有关这些更改的更多详细信息,请参阅上面的 新增功能 安全部分 。
杂项
ContentType.__str__()
现在包含模型的app_label
以消除不同应用程序中具有相同名称的模型的歧义。- 因为在会话中而不是在 cookie 中访问语言已被弃用,
LocaleMiddleware
不再在会话中查找用户的语言,并且 django.contrib.auth.logout() 不再保留注销后会话的语言。 - django.utils.html.escape() 现在使用
html.escape()
来转义 HTML。 这会将'
转换为'
,而不是之前的等效十进制代码'
。 django-admin test -k
选项现在用作unittest -k
选项,而不是--keepdb
的快捷方式。- 支持
pywatchman
< 1.2.0 被删除。 - urlencode() 现在将可迭代值编码为
doseq=False
时的原样,而不是迭代它们,使其与标准库urllib.parse.urlencode()
函数保持一致。 intword
模板过滤器现在将1.0
翻译为单数短语,将所有其他数值翻译为复数。 对于某些语言,这可能不正确。- 为模型的 ForeignKey 或 OneToOneField
'_id'
属性赋值现在会取消设置相应的字段。 之后访问该字段将导致查询。 - patch_vary_headers() 现在根据 RFC 7231#section-7.1.4 处理星号
'*'
,即 如果标题字段名称列表包含星号,则Vary
标题将由单个星号'*'
组成。 - 在 MySQL 8.0.16+ 上,
PositiveIntegerField
和PositiveSmallIntegerField
现在包含检查约束以防止数据库中出现负值。 alias=None
添加到 Expression.get_group_by_cols() 的签名中。RegexPattern
,由 re_path() 使用,不再返回带有None
值的关键字参数,以传递给缺少的可选命名组的视图。
3.0 中弃用的功能
django.utils.encoding.force_text() 和 smart_text()
不推荐使用 smart_str()
和 force_str()
的 smart_text()
和 force_text()
别名(自 Django 2.0 起)。 如果您的代码支持 Python 2,请忽略此弃用,因为 smart_str()
和 force_str()
的行为在那里不同。
杂项
django.utils.http.urlquote()
、urlquote_plus()
、urlunquote()
和urlunquote_plus()
已弃用,取而代之的是它们作为别名的函数:urllib.parse.quote()
、[ X125X]、unquote()
和unquote_plus()
。django.utils.translation.ugettext()
、ugettext_lazy()
、ugettext_noop()
、ungettext()
和ungettext_lazy()
已弃用,取而代之的是它们作为别名的函数: X125X]django.utils.translation.gettext()、gettext_lazy()、gettext_noop()、ngettext()和 ()。- 为了限制会话的创建并因此支持某些缓存策略,django.views.i18n.set_language() 将停止在 Django 4.0 的会话中设置用户的语言。 从 Django 2.1 开始,语言总是存储在 :setting:`LANGUAGE_COOKIE_NAME` cookie 中。
django.utils.text.unescape_entities()
已弃用,取而代之的是html.unescape()
。 请注意,与unescape_entities()
不同,html.unescape()
立即计算惰性字符串。- 为避免可能对有效范围造成混淆,私有内部实用程序
is_safe_url()
被重命名为url_has_allowed_host_and_scheme()
。 URL 具有允许的主机和方案通常并不意味着它是“安全的”。 例如,它可能仍然被错误地引用。 确保还在不受信任的 URL 的路径组件上使用 iri_to_uri()。
3.0 中删除的功能
这些功能已达到弃用周期的终点,并在 Django 3.0 中删除。
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅 2.0 中弃用的功能。
django.db.backends.postgresql_psycopg2
模块被移除。django.shortcuts.render_to_response()
被移除。DEFAULT_CONTENT_TYPE
设置被删除。HttpRequest.xreadlines()
被移除。- 删除了对
Field.from_db_value()
和Expression.convert_value()
的context
参数的支持。 - 删除了
QuerySet.earliest()
和latest()
的field_name
关键字参数。
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅 2.1 中弃用的 功能。
ForceRHR
GIS 功能被移除。django.utils.http.cookie_date()
被移除。staticfiles
和admin_static
模板标签库被删除。django.contrib.staticfiles.templatetags.staticfiles.static()
被移除。