2020 年 8 月 4 日
欢迎来到 Django 3.1 版本!
此版本说明涵盖了一些 新特性 ,以及从 Django 3.0 或更早版本升级时需要注意的 向后不兼容 的地方。我们已经 删除了一些过期的功能 ,并且已经开始 淘汰一些特性 。
如果你要更新现有的项目,请看 升级 Django 到最新的版本 指南。
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 配置¶新的 DEFAULT_HASHING_ALGORITHM 过渡性配置允许指定默认的哈希算法,用于对 cookie、管理员站点中的密码重置令牌、用户会话以及 django.core.signing.Signer 和 django.core.signing.dumps() 创建的签名进行编码。
Django 3.1 中增加了对 SHA-256 的支持。如果你要将同一个项目的多个实例升级到 Django 3.1,你应该在过渡期间将 :set:`DEFAULT_HASHING_ALGORITHM` 设置为 'sha1',以便与旧版本的 Django 兼容。请注意,这需要 Django 3.1.1+。一旦过渡到 3.1,你可以停止覆盖 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月 07, 2021