2020 年 8 月 4 日
欢迎来到 Django 3.1 版本!
此版本说明涵盖了一些 新特性 ,以及从 Django 3.0 或更早版本升级时需要注意的 向后不兼容 的地方。我们已经 删除了一些过期的功能 ,并且已经开始 淘汰一些特性 。
如果你要更新现有的项目,请看 How to upgrade Django to a newer version 指南。
Django 3.1 支持 Python 3.6、3.7、3.8 和 3.9(从 3.1.3 开始)。我们 强烈推荐 且官方只支持每个系列的最新版本。
Django 现在支持完全异步的请求路径,包括:
要开始使用异步视图,你需要使用 async def
来声明一个视图:
async def my_view(request):
await asyncio.sleep(0.5)
return HttpResponse('Hello, async world!')
无论你是在 WSGI 或 ASGI 模式下运行,都支持所有的异步功能。但是,在 WSGI 模式下使用 async 代码会有性能上的惩罚。你可以在 异步支持 文档中阅读更多的具体内容。
你可以自由地混合异步和同步视图、中间件和测试,只要你愿意。Django 会确保你最终使用正确的执行上下文。我们希望大多数项目会保持大部分视图的同步,只有少数视图在异步模式下运行,但这完全是你的选择。
Django 的 ORM、缓存层和其他做长期网络调用的代码还不支持异步访问。我们希望在即将发布的版本中增加对它们的支持。但是,异步视图是很理想的,如果你在视图里面做了大量的 API 或 HTTP 调用,你现在可以原生地将所有这些 HTTP 调用并行进行,以大大加快你的视图的执行速度。
异步支持应该是完全向后兼容的,我们已经尝试确保它不会对你现有的同步代码造成速度上的倒退。它应该不会对任何现有的 Django 项目产生明显的影响。
Django 现在包含 models.JSONField
和 forms.JSONField
,可以在所有支持的数据库后端使用。这两个字段都支持使用自定义 JSON 编码器和解码器。模型字段支持自省、查找和变换,这些功能以前只有 PostgreSQL 才有:
from django.db import models
class ContactInfo(models.Model):
data = models.JSONField()
ContactInfo.objects.create(data={
'name': 'John',
'cities': ['London', 'Cambridge'],
'pets': {'dogs': ['Rufus', 'Meg']},
})
ContactInfo.objects.filter(
data__name='John',
data__pets__has_key='dogs',
data__cities__contains='London',
).delete()
如果你的项目使用了 django.contrib.postgres.fields.JSONField
,加上相关的表单字段和变换,你应该调整使用新的字段,并生成和应用数据库迁移。目前,旧的字段和变换体作为新字段的引用留存下来,并且 从这个版本开始取消。
DEFAULT_HASHING_ALGORITHM
配置¶The new DEFAULT_HASHING_ALGORITHM
transitional setting allows specifying
the default hashing algorithm to use for encoding cookies, password reset
tokens in the admin site, user sessions, and signatures created by
django.core.signing.Signer
and django.core.signing.dumps()
.
Support for SHA-256 was added in Django 3.1. If you are upgrading multiple
instances of the same project to Django 3.1, you should set
DEFAULT_HASHING_ALGORITHM
to 'sha1'
during the transition, in order to
allow compatibility with the older versions of Django. Note that this requires
Django 3.1.1+. Once the transition to 3.1 is complete you can stop overriding
DEFAULT_HASHING_ALGORITHM
.
因为在 Django 4.0 中,对使用 SHA-1 算法的令牌、cookie、会话和签名的支持将被取消,所以这个配置从这个版本开始就被取消了。
django.contrib.admin
¶新的 django.contrib.admin.EmptyFieldListFilter
为 ModelAdmin.list_filter
允许在管理的变更列表视图中过滤空值(空字符串和空值)。
管理员更改列表视图右侧的过滤器现在包含一个清除所有过滤器的链接。
管理员现在在大屏幕上有一个侧栏,以便于导航。它是默认启用的,但可以通过使用一个自定义的 AdminSite
和设置 AdminSite.enable_nav_sidebar
为 False
来禁用。
渲染侧边栏需要访问当前请求,以便设置 CSS 和 ARIA 角色的负担。这就需要使用 OPTIONS
的 'context_processors'
选项中的 'django.template.context_processors.request'
。
最初的空 extra
内联现在可以被删除,与动态创建的内联相同。
XRegExp
从 2.0.0 版本升级到 3.2.0。
jQuery 从 3.4.1 版本升级到 3.5.1。
Select2 库从 4.0.7 版本升级到 4.0.13。
django.contrib.auth
¶PASSWORD_RESET_TIMEOUT
配置允许定义密码重置链接的有效秒数。我们鼓励这样做,而不是使用被废弃的 PASSWORD_RESET_TIMEOUT_DAYS
配置,后者将在 Django 4.0 中被删除。AbstractBaseUser.get_session_auth_hash()
现在使用 SHA-256 散列算法。在 Django 4.0 之前,对使用旧的散列算法的用户会话的支持仍然存在。django.contrib.contenttypes
¶remove_stale_contenttypes --include-stale-apps
选项允许从以前安装的应用程序中删除陈旧的内容类型,这些应用程序已经从 INSTALLED_APPS
中删除。django.contrib.gis
¶relate
查找现已在 MariaDB 上支持。LinearRing.is_counterclockwise
属性。AsGeoJSON
现已在 Oracle 上支持。AsWKB
和 AsWKT
函数。django.contrib.humanize
¶intword
模板过滤器现在支持负整数。django.contrib.postgres
¶BloomIndex
类允许在数据库中创建 bloom
索引。新的 BloomExtension
迁移操作安装 bloom
扩展来增加对该索引的支持。get_FOO_display()
现在支持 ArrayField
和 RangeField
。rangefield.lower_inc
, rangefield.lower_inf
、rangefield.upper_inc
和 rangefield.upper_inf
查找允许通过绑定类型查询 RangeField
。rangefield.contained_by
现在支持 SmallAutoField
、AutoField
、BigAutoField
、SmallIntegerField
和 DecimalField
。SearchQuery
现在支持 PostgreSQL 11+ 上的 'websearch'
搜索类型。SearchQuery.value
现在支持查询表达式。SearchHeadline
类可以高亮显示搜索结果。search
查找现在支持查询表达式。SearchRank
的 cover_density
参数允许按覆盖密度进行排名。SearchRank
的新 normalization
参数允许进行排名规范化。ExclusionConstraint.deferrable
属性允许创建可推迟的排除约束。django.contrib.sessions
¶SESSION_COOKIE_SAMESITE
配置现在允许 'None'
(字符串)值明确表示所有同站和跨站请求都会发送 cookie。cache_control()
装饰器和 patch_cache_control()
方法现在支持 Cache-Control
头的 no-cache
指令中的多个字段名。delete()
现在如果键被成功删除,返回 True
,否则返回 False
。CSRF_COOKIE_SAMESITE
配置现在允许 'None'
(字符串)值来明确说明所有同站和跨站请求都会发送 cookie。EMAIL_FILE_PATH
配置,现在支持 pathlib.Path
。django.view.debug.SafeExceptionReporterFilter
现在可以过滤异常报告中 request.META
中的敏感值。SafeExceptionReporterFilter.cleansed_substitute
和 SafeExceptionReporterFilter.hidden_settings
属性允许在异常报告中自定义敏感配置和 request.META
过滤。DEFAULT_EXCEPTION_REPORTER_FILTER
。DEFAULT_EXCEPTION_REPORTER
允许提供 django.views.debug.ExceptionReporter
子类来定制异常报告的生成。详情请参见 自定义错误报告。FileSystemStorage.save()
方法现在支持 pathlib.Path
。FileField
和 ImageField
现在可以接受 storage
的调用。这允许你在运行时修改所使用的存储,例如为不同的环境选择不同的存储。ModelChoiceIterator
,被 ModelChoiceField
和 ModelMultipleChoiceField
使用,现在使用 ModelChoiceIteratorValue
,可以被部件用来访问模型实例。详情请看 迭代关系选择。
django.forms.DateTimeField
现在接受 ISO 8601 日期时间格式的子集,包括可选的时区,例如 2019-10-10T06:47
、2019-10-10T06:47:23+04:00
或 2019-10-10T06:47:23Z
。如果提供了时区,将始终保留时区,即使 USE_TZ
为 False
时,也会返回时区感知的日期时间。
此外,DateTimeField
现在在将字段输入转换为 datetime
值时,除了使用 DATETIME_INPUT_FORMATS
外,还使用 DATE_INPUT_FORMATS
。
MultiWidget.widgets
现在接受一个字典,允许自定义子部件 name
属性。
新的 BoundField.widget_type
属性可用于根据部件类型动态调整表单渲染。
LANGUAGE_COOKIE_SAMESITE
配置现在允许 'None'
(字符串)值明确表示所有同站和跨站请求都会发送 cookie。check --database
选项允许指定数据库别名,以便运行 database
系统检查。以前,通过向命令传递 database
标签,为所有设置的 DATABASES
启用这些检查。migrate --check
选项使命令在检测到未应用的迁移时以非零状态退出。CommandError
的新 ``returncode``参数允许自定义管理命令的退出状态。dbshell -- ARGUMENTS
选项允许向数据库的命令行客户端传递额外的参数。flush
和 sqlflush
命令现在包括 SQL 来重置 SQLite 上的序列。ExtractIsoWeekDay
函数从 DateField
和 DateTimeField
中提取 ISO-8601 周天,新的 iso_week_day
查询可以按 ISO-8601 周天查询。QuerySet.explain()
现在支持:TREE
格式,analyze
选项。PositiveBigIntegerField
,它的作用很像 PositiveIntegerField
,只是它只允许在一定(依赖于数据库的)限制下取值。从 0
到 9223372036854775807
的值在 Django 支持的所有数据库中都是安全的。RESTRICT
选项为 ForeignKey`
和 OneToOneField
的 on_delete
参数模拟了 SQL 约束 ON DELETE RESTRICT
的行为。CheckConstraint.check
现在支持布尔表达式。RelatedManager.add()
、create()
和 set()
方法现在接受可调用对象参数作为 through_defaults
参数的值。QuerySet.datetimes()
的新 is_dst
参数决定了如何处理不存在和不明确的日期。F
表达式 bitxor()
方法允许 bitwise XOR 操作。QuerySet.bulk_create()
在使用 MariaDB 10.5+ 时,现在可以设置对象的主键。DatabaseOperations.sql_flush()
方法现在可以在 MySQL 上生成更有效的 SQL,对于不需要重置序列的表,使用 DELETE
而不是 TRUNCATE
语句。deterministic
。这允许在检查约束和部分索引中使用它们。UniqueConstraint.deferrable
属性允许创建可推迟的唯一约束。ALLOWED_HOSTS
为空且 DEBUG=True
,则在 Host
头中允许使用 localhost 的子域,例如 static.localhost
。HttpResponse.set_cookie()
和 HttpResponse.set_signed_cookie()
现在允许使用 samesite='None'
(字符串)来明确说明所有同站和跨站请求都会发送cookie。HttpRequest.accepts()
方法根据 Accept
HTTP 头返回请求是否接受给定的 MIME 类型。SECURE_REFERRER_POLICY
配置现在默认为 'same-origin'
。设置了这个之后,SecurityMiddleware
会在所有还没有设置 Referrer 政策 头的情况下,将其设置为 same-origin
。这可以防止 Referer
头被发送到其他来源。如果你需要以前的行为,明确地设置 SECURE_REFERRER_POLICY
为 None
。
django.core.signing.Signer
、django.core.signing.load()
和 django.core.signing.dumps()
的默认算法改为 SHA-256。在 Django 4.0 之前,仍然支持用旧的 SHA-1 算法进行签名。
另外,Signer
的新 algorithm
参数允许自定义哈希算法。
translate
和 blocktranslate
模板标签被引入,用于模板代码的国际化。旧的 trans
和 blocktrans
模板标签的别名继续工作,并将在可预见的未来保留。include
模板标签现在接受模板名称的可迭代对象。SimpleTestCase
现在实现了 debug()
方法,允许在不收集结果和捕获异常的情况下运行测试。这可以用来支持在调试器下运行测试。MIGRATE
测试数据库配置允许在创建测试数据库时禁止迁移。test --buffer
选项,以丢弃通过测试的输出。DiscoverRunner
现在会跳过对非 测试所引用 的数据库进行系统检查。TransactionTestCase
关闭现在在 MySQL 上的速度更快了,这是因为 flush
命令的改进。作为一个副作用,后者不会再在关闭时自动重置序列。如果你的测试需要这个功能,请启用 TransactionTestCase.reset_sequences
。filepath_to_uri()
现在支持 pathlib.Path
。parse_duration()
现在支持 ISO 8601 格式的小数点用逗号分隔。parse_datetime()
、parse_duration()
和 parse_time()
现在支持用逗号分隔毫秒。pathlib.Path
为 NAME
的配置。startproject
命令生成的 settings.py
现在使用 pathlib.Path
代替 os.path
来建立文件系统路径。TIME_ZONE
设置。本节介绍了第三方数据库后端可能需要的更改。
DatabaseOperations.fetch_returned_insert_columns()
现在需要一个额外的 returning_params
参数。connection.timezone
属性现在默认为 'UTC
,或者当 USE_TZ
为 True
时,支持时区的数据库上的 TIME_ZONE
。此前,在支持时区的数据库上是 None
。connection._nodb_connection
属性改为 connection._nodb_cursor()
方法,现在返回一个产生游标的上下文管理器,并在退出 with
语句后自动关闭游标和连接。DatabaseClient.runshell()
现在需要一个额外的 parameters
参数,作为传递给命令行客户端的额外参数列表。DatabaseOperations.sql_flush()
的 sequences
位置参数被只用关键字的布尔参数 reset_sequences
取代。如果 True
,截断表的序列将被重置。DatabaseOperations.sql_flush()
的 allow_cascade
参数现在是一个纯关键字的参数。DatabaseOperations.execute_sql_flush()
的 using
位置参数被删除。该方法现在使用被调用实例的数据库。JSONField
的支持,或者将 DatabaseFeatures.supports_json_field
设置为 False
。如果不支持存储基元,则设置 DatabaseFeatures.supports_primitives_in_json_field
为 False
。如果 JSON 的数据类型为真,则设置 DatabaseFeatures.has_native_json_field
为 True
。如果不支持 jsonfield.contains
和 jsonfield.contains_by
,则将 DatabaseFeatures.support_json_field_contains
设置为 False
。JSONField
的自省,或者将 can_introspect_json_field
设置为 False
。对 MariaDB 10.1 的上游支持在 2020 年 10 月结束。Django 3.1 支持 MariaDB 10.2 及以上版本。
AbstractUser.first_name
的 max_length
增加到 150¶包含了 django.contrib.auth.models.User.first_name
的迁移。如果你有一个继承自 AbstractUser
的自定义用户模型,你将需要为你的用户模型生成并应用数据库迁移。
如果你想保留 first name 的 30 个字符限制,请使用自定义表单:
from django import forms
from django.contrib.auth.forms import UserChangeForm
class MyUserChangeForm(UserChangeForm):
first_name = forms.CharField(max_length=30, required=False)
如果你想在管理中编辑用户时保留这个限制,请将 UserAdmin.form
设置为使用这个表单:
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class MyUserAdmin(UserAdmin):
form = MyUserChangeForm
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
cache
使用的缓存密钥和 make_template_fragment_key()
生成的缓存密钥与旧版本 Django 生成的密钥不同。升级到 Django 3.1 后,第一次请求任何之前缓存的模板片段都会被缓存错过。set_language()
视图中返回重定向回退或 204 HTTP 响应背后的逻辑现在是基于 Accept
HTTP 头而不是 X-Requested-With
HTTP 头的存在。django.db.models.query
、django.db.models.sql
和 django.db.models.sql.datastructures
中的 django.core.exceptions.EmptyResultSet
的兼容性导入被移除。django.db.models.field
中 django.core.exceptions.FieldDoesNotExist
的兼容性导入。django.forms.utils.pretty_name()
和 django.forms.boundfield.BoundField
的兼容性导入。django.template.base
中的 Context
、ContextPopException
和 RequestContext
的兼容性导入被移除。django.contrib.admin.helpers.ACTION_CHECKBOX_NAME
中的兼容性导入。STATIC_URL
和 MEDIA_URL
配置现在以服务器提供的 SCRIPT_NAME
的值为前缀(如果没有设置,则为 /
)。这一变化不应影响设置为有效 URL 或绝对路径的配置。ConditionalGetMiddleware
不再为空 content
的响应添加 ETag
头。django.utils.disturators.classproperty()
装饰器被公开并移到 django.utils.functional.classproperty()
。floatform
模板过滤器现在对四舍五入为零的负数输出(正)``0```。Meta.ordering
和 Meta.unique_together <django.db.models.Options.unique_together>`
模块中模型的选项,以前是元组,现在是列表。DATETIME_INPUT_FORMATS
的默认列表中删除了仅限日期的格式。FileInput
小部件不再使用 required
HTML 属性进行渲染。django.views.debug.ExceptionReporterFilter
类。根据 自定义错误报告 文档,与 DEFAULT_EXCEPTION_REPORTER_FILTER
一起使用的类需要继承 django.views.debug.SafeExceptionReporterFilter
。cache_page()
装饰器设置的缓存超时现在优先于 Cache-Control
头的 max-age
指令。ForeignKey.to_field
参数中提供一个非本地的远程字段,现在会引发 FieldError
。SECURE_REFERRER_POLICY
现在默认为 'same-origin'
。更多细节请参见 新变化 安全章节。check
管理命令现在只对使用 check --database
选项指定的数据库别名运行 database
系统检查。migrate
管理命令现在只运行 database
系统检查要迁移的数据库。row1
和 row2
被删除,取而代之的是 :nth-child(odd)
和 :nth-child(even)
伪类。make_password()
函数现在要求其参数为字符串或字节。其他类型的参数应该显式地转换为其中之一。AsKML
函数中未记录的 version
参数。dumpdata
使用,现在默认使用 Unicode 转储所有数据。如果你需要以前的行为,传递 ensure_ascii=True
给 JSON 序列化器,或者 allow_unicode=False
给 YAML 序列化器。mysqlclient
的最低支持版本从 1.3.13 增加到 1.4.0。django.contrib.postgres.forms.InvalidJSONInput
和 django.contrib.postgres.forms.JSONString
被移至 django.forms.field
。django.contrib.postgres.field.jsonb.JsonAdapter
类。{% localize off %}
标签和 unlocalize
过滤器不再遵守 DECIMAL_SEPARATOR
配置。asgiref
的最低支持版本从 3.2 增加到 3.2.10。type
属性来渲染 <script>
标签,以遵循 WHATWG 建议 。ModelChoiceIterator
,由 ModelChoiceField
和 ModelMultipleChoiceField
使用,现在产生 2 个包含 ModelChoiceIteratorValue
实例的选择,作为每个选择的第一个 value
元素。在大多数情况下,这个代理是透明的,但如果你需要 field
值本身,请使用 ModelChoiceIteratorValue.value
属性代替。JSONField
¶django.contrib.postgres.field.JSONField
和 django.contrib.postgres.forms.JSONField
被废弃,改用 models.JSONField
和 forms.JSONField
。
未记录的 django.contrib.postgres.fields.jsonb.KeyTransform
和 django.contrib.postgres.fields.jsonb.KeyTextTransform
也被弃用,改用 django.db.models.fields.json
中的变换。
新的 JSONField
、KeyTransform
和 KeyTextTransform
可用于所有支持的数据库后端。
PASSWORD_RESET_TIMEOUT_DAYS
配置已被取消,改为 PASSWORD_RESET_TIMEOUT
。
未记录的 isnull
查找使用非布尔值作为右侧的用法已被废弃,请使用 True
或 False
代替。
勉强记录的 django.db.models.query_utils.InvalidQuery
异常类被废弃,取而代之的是 FieldDoesNotExist
和 FieldError
。
django-admin.py
的入口点已被废弃,改为 django-admin
。
HttpRequest.is_ajax()
方法已被废弃,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前的用法倾向于使用 JavaScript Fetch API 。根据你的用例,你可以写你自己的 AJAX 检测方法,或者使用新的 HttpRequest.accepts()
方法,如果你的代码依赖于客户端 Accept
HTTP 头。
如果你正在编写自己的 AJAX 检测方法,request.is_ajax()
可以完全复制为 request.headers.get('x-requested-with') == 'XMLHttpRequest'
。
传递 None
作为 django.utils.deprecation.MiddlewareMixin.__init__()
的第一个参数是过时的。
CookieStorage
使用的 cookie 值的编码格式与旧版本 Django 生成的格式不同。在 Django 4.0 之前,仍然支持旧的格式。
会话的编码格式与旧版 Django 生成的格式不同。在 Django 4.0 之前,仍然支持旧的格式。
Signal
的纯文档化 providing_args
参数已被废弃。如果你依赖这个参数作为文档,你可以将文本移到代码注释或 docstring 中。
没有 length
参数的情况下调用 django.utils.crypto.get_random_string()
已被废弃。
ModelMultipleChoiceField
的 list
信息已被弃用,改为 invalid_list
。
向 QuerySet.order_by()
传递原始列别名已经被废弃。通过事先在 RawSQL
中传递别名,可以达到同样的效果。
NullBooleanField
模型字段被废弃,改为 BooleanField(null=True)
。
django.conf.urls.url()
的 django.urls.re_path()
别名已被废弃。
{% ifequal %}
和 {% ifnotequal %}
模板标签已被废弃,改为 {% if %}
。{% if %}
涵盖了所有的用例,但如果你需要继续使用这些标签,可以将它们从 Django 中提取到一个模块中,并作为一个内置标签包含在 'buildins'
选项中的 OPTIONS
中。
DEFAULT_HASHING_ALGORITHM
过渡性配置已废弃。
这些功能已经到了废弃周期,在 Django 3.1 中被删除。
参见 在 2.2 中被废弃的功能,了解这些变化的细节,包括如何删除这些功能的使用。
django.utils.timezone.FixedOffset
被删除。django.core.paginator.QuerySetPaginator
被删除。Meta.ordering
不影响 GROUP BY
的查询。django.contrib.postgres.fields.FloatRangeField
和 django.contrib.postgres.forms.FloatRangeField
被删除。FILE_CHARSET
配置被删除。django.contrib.staticfiles.storage.CachedStaticFilesStorage
被删除。RemoteUserBackend.configure_user()
方法需要 request
作为第一个位置参数。SimpleTestCase.allow_database_queries
和 TransactionTestCase.multi_db
的支持。12月 13, 2021