Django 1.11 版本发布说明:新特性与升级指南
创始人
2026-05-02 07:52:04
0

Django 1.11 版本发行说明

2017 年 4 月 4 日

欢迎来到 Django 1.11 版本!

这些发布说明涵盖了 新功能,以及一些 不兼容变更,当您从 Django 1.10 或更早版本升级时,您需要注意。我们已经 开始了一些功能的弃用过程

如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。

Django 1.11 被指定为 长期支持版本。它将在发布后至少三年内接收安全更新。对于之前的 LTS 版本 Django 1.8,支持将于 2018 年 4 月结束。

Python 兼容性

Django 1.11 需要 Python 2.7、3.4、3.5、3.6 或 3.7(截止到 1.11.17 版本)。我们* 强烈建议* 并且只正式支持每个系列的最新版本。

Django 1.11.x 系列是支持 Python 2 的最后一个版本。下一个主要版本,Django 2.0,将仅支持 Python 3.4+。

弃用警告默认不再大声发出

与旧版本的 Django 不同,Django 自身的弃用警告默认不再显示。这与 Python 的默认行为一致。

此更改允许第三方应用在不添加用于避免弃用警告的代码的情况下同时支持 Django 1.11 LTS 和 Django 1.8 LTS 。

在发布 Django 2.0 后,我们建议第三方应用的作者停止支持所有在 1.11 之前的 Django 版本。在那时,您应该能够使用 python -Wd 运行您包的测试,以确保弃用警告出现。在修复弃用警告后,您的应用应该与 Django 2.0 兼容。

Django 1.11 新特性

基于类的模型索引

新的 django.db.models.indexes 模块包含了用于简化创建数据库索引的类。索引可以通过在模型中使用 Meta.indexes 选项来添加。

Index 类创建一个 b-tree 索引,就像你在模型字段上使用 db_index 或在模型 Meta 类上使用 index_together 一样。它可以被子类化以支持不同的索引类型,例如 GinIndex。它还允许定义索引列的顺序(ASC/DESC)。

基于模板的小部件渲染

为了方便定制小部件,现在表单小部件的渲染是使用模板系统而不是在 Python 中进行的。请参阅 表单渲染 API

你可能需要调整你编写的任何自定义小部件,以适应一些 不兼容变更

Subquery 表达式

新的 SubqueryExists 数据库表达式允许创建明确的子查询。子查询可以使用 OuterRef 类引用来自外部查询集的字段。

次要特性

django.contrib.admin

django.contrib.auth

  • PBKDF2 密码哈希器的默认迭代次数增加了 20 %。

  • LoginViewLogoutView 基于类的视图替代了已弃用的 login()logout() 基于函数的视图。

  • PasswordChangeViewPasswordChangeDoneViewPasswordResetViewPasswordResetDoneViewPasswordResetConfirmViewPasswordResetCompleteView 基于类的视图替代了已弃用的 password_change(), password_change_done(), password_reset(), password_reset_done(), password_reset_confirm(), 和 password_reset_complete() 基于函数的视图。

  • PasswordResetConfirmView 的新属性 post_reset_login 允许在成功重置密码后自动登录用户。如果配置了多个 AUTHENTICATION_BACKENDS,可以使用 post_reset_login_backend 属性选择要使用的后端。

  • 为了避免通过 HTTP Referer 标头泄露密码重置令牌的可能性(例如,如果重置页面包含对托管在另一个域上的 CSS 或 JavaScript 的引用),PasswordResetConfirmView (但不是已弃用的 password_reset_confirm() 基于函数的视图)将令牌存储在会话中,并重定向到自身,以向用户呈现不带令牌的 URL 的密码更改表单。

  • update_session_auth_hash() 现在会旋转会话密钥,以允许密码更改来使被窃取的会话 Cookie 失效。

  • LoginViewLogoutView 的新属性 success_url_allowed_hosts 允许指定一组安全的主机,用于在登录和注销后进行重定向。

  • 已添加密码验证器的 help_textUserCreationForm

  • HttpRequest 现在传递给 authenticate(),如果身份验证后端接受 request 参数,则它将传递给身份验证后端。

  • user_login_failed() 信号现在接收一个 request 参数。

  • PasswordResetForm 支持自定义用户模型,该模型使用名称不是 'email' 的电子邮件字段。将 CustomUser.EMAIL_FIELD 设置为字段的名称。

  • get_user_model() 现在可以在导入时调用,即使在定义模型的模块中也可以。

django.contrib.contenttypes

  • remove_stale_contenttypes 命令中,当检测到陈旧的内容类型时,现在会列出一系列相关对象,如 auth.Permission,这些对象也将被删除。之前,只列出了内容类型(而且此提示是在 migrate 之后,而不是在一个单独的命令中)。

django.contrib.gis

  • 新的 GEOSGeometry.from_gml()OGRGeometry.from_gml() 方法允许从 GML 创建几何图形。

  • 在 SpatiaLite 上新增了对 dwithin 查询的支持。

  • Area 函数、Distance 函数以及距离查询现在在 SpatiaLite 上支持大地坐标。

  • 基于 OpenLayers 的表单小部件现在使用来自 https://cdnjs.cloudflare.comOpenLayers.js,这比旧的 https://openlayers.org/ 源更适合生产使用。它们还更新为使用 OpenLayers 3。

  • PostGIS 迁移现在可以改变字段尺寸。

  • 现在可以在创建 GDALRaster 对象时传递 sizeshapeoffset 参数。

  • 新增了对 IsValid 函数、MakeValid 函数以及 isvalid 查询的 SpatiaLite 支持。

  • 新增了对 Oracle 数据库的支持,包括 AsGML 函数、BoundingCircle 函数、IsValid 函数以及 isvalid 查询。

django.contrib.postgres

  • StringAgg 的新参数 distinct 决定了连接的值是否要去重。

  • 新的 GinIndexBrinIndex 类允许在数据库中创建 GINBRIN 索引。

  • django.contrib.postgres.fields.JSONField 接受一个新的参数 encoder,用于指定自定义类以编码不受标准编码器支持的数据类型。

  • 新的 CIText 混合类和 CITextExtension 迁移操作允许在 PostgreSQL 中使用 citext 扩展来进行不区分大小写的查找。提供了三个字段:CICharFieldCIEmailFieldCITextField

  • 新的 JSONBAgg 允许将值聚合为 JSON 数组。

  • HStoreField (模型字段)和 HStoreField (表单字段)允许存储空值。

缓存

  • Memcached 后端现在将 OPTIONS 的内容作为关键字参数传递给客户端构造函数,允许更高级的客户端行为控制。请参阅 cache arguments 文档以获取示例。

  • Memcached 后端现在允许在 LOCATION 中定义多个服务器,使用逗号分隔的字符串,以方便处理使用这种字符串的环境变量的第三方服务。

CSRF

  • 新增了 CSRF_USE_SESSIONS 设置,允许将 CSRF 令牌存储在用户的会话中,而不是在 cookie 中。

数据库后端

  • Added the skip_locked argument to QuerySet.select_for_update() on PostgreSQL 9.5+ and Oracle to execute queries with FOR UPDATE SKIP LOCKED.

  • 新增了 TEST['TEMPLATE'] 设置,允许 PostgreSQL 用户指定用于创建测试数据库的模板。

  • QuerySet.iterator() now uses server-side cursors on PostgreSQL. This feature transfers some of the worker memory load (used to hold query results) to the database and might increase database memory usage.

  • 新增了对在 OPTIONS 中使用 'isolation_level' 选项的 MySQL 支持,允许指定 事务隔离级别。为了避免可能的数据丢失,建议从 MySQL 的默认级别 repeatable read 切换到 read committed。

  • 新增了对 cx_Oracle 5.3 的支持。

电子邮件

  • 新增了 EMAIL_USE_LOCALTIME 设置,允许将 SMTP 日期标头发送到本地时区,而不是 UTC。

  • EmailMessage.attach()attach_file() 现在在为 text/* 附件指定无法解码为 UTF-8 的二进制内容时,会回退到 MIME 类型 application/octet-stream

文件存储

  • 为了能够被 io.TextIOWrapper 包装,File 现在具有 readable()writable()seekable() 方法。

表单

国际化

  • 数字格式化和 NUMBER_GROUPING 设置支持非均匀的数字分组。

管理命令

迁移

  • 新增了对 uuid.UUID 对象的序列化支持。

模型

请求和响应

序列化

  • 新的 django.core.serializers.base.Serializer.stream_class 属性允许子类自定义默认流。

  • 可以通过向 serializers.serialize() 函数传递一个 cls 关键字参数来自定义 JSON 序列化器 使用的编码器。

  • DjangoJSONEncoder 现在可以序列化 timedelta 对象(被 DurationField 使用)。

模板

  • 现在可以将 mark_safe() 用作装饰器。

  • Jinja2 模板后端现在支持通过在 OPTIONS 中设置 'context_processors' 选项来配置上下文处理器。

  • regroup 标签现在返回 namedtuple 而不是字典,因此你可以在循环中直接解包组对象,例如 {% for grouper, list in regrouped %}

  • 新增了 resetcycle 模板标签,允许重置 cycle 模板标签的序列。

  • 现在可以为特定的 filesystem.Loader 指定特定的目录。

测试

验证器

1.11 中的向后不兼容更改

django.contrib.gis

  • 为了简化代码库并且因为现在安装起来更容易(相对于最初发布 contrib.gis 时的情况),现在在 GeoDjango 中需要 GDAL 作为依赖。在旧版本中,它只对 SQLite 有要求。

  • contrib.gis.maps 已被移除,因为它与已退役的 Google Maps API 版本进行交互,似乎没有维护。如果您正在使用它,请 告诉我们

  • GEOSGeometry 的等号运算符现在也会比较 SRID。

  • 基于 OpenLayers 的表单小部件现在使用 OpenLayers 3,同时更新了 gis/openlayers.htmlgis/openlayers-osm.html 模板。如果您对这些小部件进行子类化或扩展模板,请检查您的项目。此外,新的小部件与旧的小部件有一些不同。不再使用小部件中的工具栏,而是点击以绘制,点击并拖动以移动地图,以及点击并拖动一个点/顶点/角来移动它。

  • 不再支持 SpatiaLite < 4.0 。

  • 不再支持 GDAL 1.7 和 1.8 。

  • contrib.gis.forms.widgets 中的小部件和管理员的 OpenLayersWidget 现在使用 表单渲染 API 而不是 loader.render_to_string()。如果您使用自定义小部件模板,您需要确保您的表单渲染器可以找到它。例如,您可以使用 TemplatesSetting 渲染器。

django.contrib.staticfiles

  • 当使用散列的静态文件存储时,如果存在引用循环(例如,'foo.css' 引用 'bar.css',而 'bar.css' 又引用 'foo.css'),或者如果引用其他文件的文件链过深,无法在多次传递中解析,那么 collectstatic 在后处理期间可能会失败。在后一种情况下,可以通过 ManifestStaticFilesStorage.max_post_process_passes 增加传递次数。

  • 当使用 ManifestStaticFilesStorage 时,运行时未在清单中找到的静态文件现在会引发 ValueError,而不是返回不变的路径。您可以通过将 ManifestStaticFilesStorage.manifest_strict 设置为 False 来恢复到旧的行为。

数据库后端 API

本节介绍了第三方数据库后端可能需要的更改。

  • 新增了 DatabaseOperations.time_trunc_sql() 方法,以支持 TimeField 截断。它接受一个 lookup_typefield_name 参数,并返回将给定时间字段 field_name 截断为只具有给定精度的时间对象的适当 SQL。lookup_type 参数可以是 'hour''minute''second'

  • 新增了 DatabaseOperations.datetime_cast_time_sql() 方法,以支持 time 查询。它接受一个 field_nametzname 参数,并返回将日期时间值强制转换为时间值所需的 SQL。

  • 要启用 FOR UPDATE SKIP LOCKED 支持,请设置 DatabaseFeatures.has_select_for_update_skip_locked = True

  • 新的 DatabaseFeatures.supports_index_column_ordering 属性指定数据库是否允许在索引中定义列的排序。默认值为 True,而 DatabaseIntrospection.get_constraints() 方法应在每个返回的字典中包含一个 'orders' 键,该键包含一个列表,其中包含与索引中每列的排序对应的 'ASC' 和/或 'DESC' 值。

  • inspectdb 不再调用已弃用的 DatabaseIntrospection.get_indexes() 方法。自定义数据库后端应确保 DatabaseIntrospection.get_constraints() 返回所有类型的索引。

  • ignores_quoted_identifier_case 功能的名称更改为 ignores_table_name_case,以更准确地反映它的使用方式。

  • 新增了 name 关键字参数到 DatabaseWrapper.create_cursor(self, name=None) 方法,以允许在支持的后端上使用服务器端游标。

不再支持 PostgreSQL 9.2 和 PostGIS 2.0 。

PostgreSQL 9.2 的上游支持将于 2017 年 9 月结束。因此,Django 1.11 将 PostgreSQL 9.3 设为其官方支持的最低版本。

由于 PostgreSQL 9.2 是支持 PostGIS 2.0 的最后一个版本,因此也取消了对 PostGIS 2.0 的支持。

此外,支持的最低 psycopg2 版本从 2.4.5 提高到 2.5.4 。

LiveServerTestCase 现在绑定到零端口

与其采用端口范围并迭代查找空闲端口,LiveServerTestCase 现在绑定到零端口,并依赖操作系统分配空闲端口。不再使用 DJANGO_LIVE_TEST_SERVER_ADDRESS 环境变量,也不再使用 manage.py test --liveserver 选项。

如果需要将 LiveServerTestCase 绑定到特定端口,可以使用 Django 1.11.2 中新增的 port 属性。

django.contrib.authi18n 视图中加强了对不安全的重定向的保护。

LoginViewLogoutView (以及已弃用的函数式等效版本)和 set_language() 在应用程序运行在 HTTPS 上时,会保护用户免受被重定向到非 HTTPS 的 next URL 的影响。

QuerySet.get_or_create()update_or_create() 现在会验证参数。

为了防止拼写错误默默通过,get_or_create()update_or_create() 检查它们的参数是否是模型字段。这只会在一个方面引入向后不兼容,可能会暴露出项目中的错误。

pytz 现在是必需的依赖项,不再支持将 settings.TIME_ZONE = None

为了简化 Django 的时区处理,pytz 现在是必需的依赖项,它会自动与 Django 一起安装。

不再支持 settings.TIME_ZONE = None,因为这种行为通常不常用且可疑的有用性。如果希望根据系统时区自动检测时区,可以使用 tzlocal

from tzlocal import get_localzone

TIME_ZONE = get_localzone().zone

这与 settings.TIME_ZONE = None 类似,但它还设置了 os.environ['TZ']。如果存在情况下,您发现无法适应设置 TIME_ZONE 的代码,请通过 告诉我们

管理模板中的 HTML 更改

class="help"> 被替换为

标签,以允许在帮助文本中包含列表。

只读字段现在被包装在 class="readonly">...

中,而不是

...

,以允许字段内容包含任何类型的 HTML。

由于引入基于模板的小部件渲染,发生了一些更改。

移除了 django.forms.widgets 中一些未记录的类:

  • SubWidget

  • RendererMixin, ChoiceFieldRenderer, RadioFieldRenderer, CheckboxFieldRenderer

  • ChoiceInput, RadioChoiceInput, CheckboxChoiceInput

移除了未记录的 Select.render_option() 方法。

移除了 Widget.format_output() 方法。请使用自定义小部件模板替代。

如果 settings.USE_L10N=True,现在某些小部件的值,如