Django 1.8 版本发行说明

2015 年 4 月 1 日

欢迎使用 Django 1.8 !

这些发布说明涵盖了 新功能,以及从 Django 1.7 或更早版本升级时需要注意的一些 不向后兼容的变更。我们还已经 开始了一些功能的弃用过程,并且一些功能已经完成了弃用过程并被 移除了

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

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

Python 兼容性

Django 1.8 需要 Python 2.7、3.2、3.3、3.4 或 3.5。我们 强烈推荐 并且只官方支持每个系列的最新版本。

Django 1.8 是第一个支持 Python 3.5 的版本。

由于 Python 3.2 在 2016 年 2 月结束了上游支持,因此在 2016 年底之后我们将不再在 Python 3.2 上测试 Django 1.8.x 。

Django 1.8 的新特性

Model._meta API

Django 现在有了一个正式的 API 用于 Model._meta,提供了一种官方支持的方式来 检索字段 并根据它们的 属性 进行过滤。

Model._meta 对象从 Django 的 0.96 版本前的 "Magic Removal" 时期就存在了,只是它不是一个官方的、稳定的 API。鉴于这一点,我们努力在可能的情况下保持与旧 API 端点的向后兼容性。然而,那些不属于新官方 API 的 API 端点已经被弃用,并最终将被移除。

多模板引擎

Django 1.8 定义了一个稳定的 API 用于集成模板后端。它内置支持 Django 模板语言和 Jinja2。它支持在同一个项目中使用多个引擎来渲染模板。了解更多关于新功能的信息,请参阅 主题指南,并查看早期版本文档中的升级说明。

安全增强

django-secure 第三方库的几个功能已经集成到 Django 中。django.middleware.security.SecurityMiddleware 提供了一些安全增强功能,用于请求/响应循环。新的 check --deploy 选项允许你检查生产设置文件,以提高站点的安全性。

新的 PostgreSQL 特有功能

Django 现在有一个模块,用于扩展 PostgreSQL 特定的功能,例如 ArrayFieldHStoreField范围字段unaccent 查找。可以在 文档 中找到有关这些功能的详细信息。

新的数据类型

  • Django 现在有一个 UUIDField 用于存储通用唯一标识符。它在 PostgreSQL 上以本地的 uuid 数据类型存储,在其他后端上以固定长度的字符字段存储。还有一个相应的 表单字段
  • Django 现在有一个 DurationField 用于存储时间段,Python 中用 timedelta 来建模。它在 PostgreSQL 上以本地的 interval 数据类型存储,在 Oracle 上以 INTERVAL DAY(9) TO SECOND(6) 存储,在其他后端上以微秒的 bigint 存储。所有后端上的日期和时间相关算术操作也得到了改进。还有一个相应的 表单字段

查询表达式、条件表达式和数据库函数

查询表达式 允许你创建、自定义和组合复杂的 SQL 表达式。这使得 annotate 能够接受除了聚合之外的表达式。聚合现在可以引用多个字段,并执行类似于 F() 对象的算术操作。order_by() 也具备接受表达式的能力。

条件表达式 允许你在查询中使用 if ... elif ... else 逻辑。

还包括了一组 数据库函数,其中包括 CoalesceConcatSubstr 等功能。

TestCase 数据设置

TestCase 已进行重构,以允许在类级别使用事务和保存点进行数据初始化。不支持事务的数据库后端,比如使用 MyISAM 存储引擎的 MySQL,仍然可以运行这些测试,但不会从改进中受益。现在,测试在两个嵌套的 atomic() 块中运行:一个用于整个类,一个用于每个测试。

  • 类方法 TestCase.setUpTestData() 添加了在类级别设置测试数据的能力。使用这种技术可以加速测试,与使用 setUp() 相比。
  • TestCase 中的 fixture 加载现在一次性完成整个 TestCase

次要特性

django.contrib.admin

  • ModelAdmin 现在具有一个 has_module_permission() 方法,允许限制在管理索引页面上对模块的访问。
  • InlineModelAdmin 现在有一个属性 show_change_link,支持显示到内联对象的更改表单的链接。
  • ModelAdmin.list_filter 中使用新的 django.contrib.admin.RelatedOnlyFieldListFilter,以将 list_filter 选项限制为与 ModelAdmin 相关联的外部对象。
  • ModelAdmin.delete_view() 在删除确认页面上显示要删除的对象的摘要信息。
  • 嵌入在管理员中的 jQuery 库已升级到 1.11.2 版本。
  • 现在可以指定 AdminSite.site_url,以便在前端网站中显示一个链接。
  • 现在可以指定 ModelAdmin.show_full_result_count,以控制是否在筛选后的管理页面上显示对象的完整计数。
  • AdminSite.password_change() 方法现在有一个 extra_context 参数。
  • 现在可以通过覆盖 AdminSite.has_permission()AdminSite.login_form 来控制谁可以登录到管理站点。base.html 模板有一个新的块 usertools,其中包含用户特定的页眉。一个新的上下文变量 has_permission,它的值来自于 has_permission(),指示用户是否可以访问站点。
  • 外键下拉菜单现在通过弹出窗口提供更改或删除相关对象的按钮。

django.contrib.admindocs

  • 现在在模型的文档字符串中解析 reStructuredText 。

django.contrib.auth

django.contrib.gis

  • 现在有一个新的 GeoJSON 序列化程序 可供使用。
  • 现在允许将子查询作为地理查找参数,例如 City.objects.filter(point__within=Country.objects.filter(continent='Africa').values('mpoly'))
  • 当数据库版本为 3.0 或更高时,SpatiaLite 后端现在支持 CollectExtent 聚合函数。
  • PostGIS 2 中的 CREATE EXTENSION postgis 和 SpatiaLite 中的 SELECT InitSpatialMetaData 初始化命令现在会被 migrate 自动执行。
  • GDAL 接口现在支持检索 栅格(图像)数据文件 的属性。
  • 已删除了 Django 1.2 中更改的 SpatialRefSysGeometryColumns 的兼容性 shims。
  • 现在所有与 GDAL 相关的异常都使用 GDALException 引发。以前的 OGRException 已保留以保持向后兼容性,但不应再使用。

django.contrib.sessions

  • 在调用 flush() 后,会删除会话 cookie。

django.contrib.sitemaps

django.contrib.sites

缓存

  • django.core.cache.backends.locmem.LocMemCache 后端的 incr() 方法现在是线程安全的。

密码学

数据库后端

  • MySQL 后端不再从 datetime 值中去掉微秒,因为 MySQL 5.6.4 及更高版本根据 datetime 字段的声明支持分数秒(当 DATETIME 包含大于 0 的分数精度时)。使用 Django 1.8 和 MySQL 5.6.4 及更高版本创建的新 datetime 数据库列将支持微秒。有关更多详细信息,请参阅 MySQL 数据库注释
  • 在使用 InnoDB 存储引擎时,MySQL 后端不再为外键创建显式索引,因为 MySQL 已经自动创建了这些索引。
  • Oracle 后端不再将 connection_persists_old_columns 特性定义为 True。相反,Oracle 现在在获取表的描述时将包括一个缓存破坏子句。

电子邮件

文件存储

  • Storage.get_available_name()Storage.save() 现在接受一个 max_length 参数,以实现存储级别的最大文件名长度约束。超过此参数的文件名将被截断。这可以防止在长文件名上追加唯一后缀时出现数据库错误,而该文件名已存在于存储中。请查看关于在自定义存储类中添加此参数的 弃用说明

表单

  • 表单小部件现在将值为 TrueFalse 的属性呈现为 HTML5 布尔属性。
  • 新的 has_error() 方法允许检查是否发生了特定错误。
  • 如果在表单上定义了 required_css_class,则必填字段的 <label> 标签将在其属性中包含此类。
  • 无序列表(<ul>)中非字段错误的呈现现在在其类列表中包括 nonfield,以区分它们和特定字段错误。
  • Field 现在接受一个 label_suffix 参数,该参数将覆盖表单的 label_suffix。这使得可以在每个字段的基础上自定义后缀 — 以前在模板中使用 {{ form.as_p }} 等快捷方式时无法覆盖表单的 label_suffix
  • SelectDateWidget 现在接受一个 empty_label 参数,该参数将在 DateField 不是必需时覆盖顶部列表选项的标签。
  • 在对 ImageField 进行清理和验证后,UploadedFile 对象将具有额外的 image 属性,其中包含用于检查文件是否为有效图像的 Pillow Image 实例。它还会使用 Pillow 确定的图像内容类型来更新 UploadedFile.content_type
  • 现在在实例化 ChoiceField 时可以传递一个可调用对象,该可调用对象返回一个选项的可迭代对象。

通用视图

国际化

  • FORMAT_MODULE_PATH 现在可以是表示模块路径的字符串列表。这允许从不同的可重用应用程序导入多个格式模块。它还允许在主要的 Django 项目中覆盖这些自定义格式。

日志

管理命令

  • 现在,从命令行调用的管理命令完成其工作后,数据库连接将始终关闭。
  • 现在还可以发现来自诸如"eggs "之类的备用软件包格式的命令。
  • 新的 dumpdata --output 选项允许指定将序列化数据写入的文件。
  • 新的 makemessages --excludecompilemessages --exclude 选项允许排除特定的区域设置不进行处理。
  • compilemessages 现在有一个 --use-fuzzy-f 选项,它将模糊的翻译包括在编译后的文件中。
  • loaddata --ignorenonexistent 选项现在会忽略已不存在的模型的数据。
  • runserver 现在使用守护线程以加快重新加载速度。
  • inspectdb 现在输出 Meta.unique_together。它还可以对 MySQL 和 PostgreSQL 数据库进行自省以获取 AutoField
  • 使用 call_command() 调用带有选项的管理命令时,选项名称可以匹配命令行选项名称(去掉初始破折号)或最终选项目标变量名称,但无论哪种情况,命令接收到的结果选项现在始终是命令选项定义中指定的 dest 名称(只要命令使用 argparse 模块)。
  • dbshell 命令现在支持 MySQL 的可选 SSL 证书颁发机构设置(--ssl-ca)。
  • 新的 makemigrations --name 允许为迁移指定自定义名称,而不是生成的名称。
  • loaddata 命令现在防止了重复的夹具加载。如果 FIXTURE_DIRS 包含重复项或默认的夹具目录路径(app_name/fixtures),则会引发异常。
  • 新的 makemigrations --exit 选项允许在没有创建迁移时退出并返回错误代码。
  • 新的 showmigrations 命令允许列出项目中的所有迁移及其依赖关系。

中间件

迁移

模型

  • 现在,Django 最多记录 9000 条查询在 connections.queries 中,以防止在调试模式下的长时间运行过程中出现过多的内存使用。
  • 现在有一个模型 Meta 选项,可以为模型的所有关联字段定义 默认相关名称
  • 在不同版本的 Django 之间对模型和查询集进行 pickling 并不是官方支持的(它可能会工作,但没有保证)。现在,一个额外的变量被添加到模型和查询集的 pickled 状态中,用来指定当前的 Django 版本,当这些对象在与其被 pickled 的版本不同的版本中 unpickle 时,Django 会引发一个 RuntimeWarning
  • 添加了 Model.from_db(),Django 在使用 ORM 加载对象时会使用这个方法。该方法允许自定义模型的加载行为。
  • 现在,extra(select={...}) 允许您使用 %%s 来转义文本中的字面 %s 序列。
  • 现在可以使用装饰器模式注册 自定义查找器
  • 新的 Transform.bilateral 属性允许创建双向变换。这些变换在查找表达式中同时应用于 lhsrhs,提供了更多复杂查找的机会。
  • 现在,当使用模式查找(例如 containsstartswith 等)与 F() 表达式作为右侧时,SQL 的特殊字符(、%、_)会得到正确的转义。在这些情况下,转义是由数据库执行的,这可能导致涉及嵌套的 REPLACE 函数调用的相对复杂的查询。
  • 现在,您可以使用 Model.refresh_from_db() 来刷新模型实例。
  • 现在,您可以使用 Model.get_deferred_fields() 获取模型的延迟加载字段集合。
  • 现在,当主键字段设置为 None 时,将使用模型字段的 default 值。

信号

  • 通过 Signal.send_robust() 返回的 (receiver, exception) 元组中的异常现在附带了其回溯信息作为 __traceback__ 属性。
  • request_started 信号中添加了 environ 参数,其中包含了来自请求的 WSGI 环境结构。
  • 现在可以从 django.core.signals 导入 setting_changed() 信号,以避免在非测试情况下加载 django.test。 Django 不再自行加载它。

系统检查框架

  • register 现在可以作为一个函数使用。

模板

  • urlize 现在支持包含顶级域名后面字符的域名链接(例如 djangoproject.com/djangoproject.com/download/)。
  • urlize 不将域名或其查询字符串末尾的感叹号视为 URL 的一部分(例如,'djangoproject.com! 中的 URL 为 djangoproject.com)。
  • 添加了一个名为 locmem.Loader 的类,它可以从 Python 字典中加载 Django 模板。
  • now 标签现在可以使用常见的语法将其输出存储在上下文变量中,例如:{% now 'j n Y' as varname %}

请求和响应

  • 现在,WSGIRequest 将尊重以 // 开头的路径。
  • 现在, HttpRequest.build_absolute_uri() 方法能够正确处理以 // 开头的路径。
  • 如果 DEBUGTrue,并且请求引发了 SuspiciousOperation 异常,将会使用详细的错误页面呈现响应。
  • QueryDictquery_string 参数现在是可选的,默认值为 None,因此可以使用 QueryDict() 来实例化一个空的 QueryDict,而不是 QueryDict(None)QueryDict('')
  • HttpRequest 对象的 GETPOST 属性现在是 QueryDict,而不再是字典,而 FILES 属性现在是一个 MultiValueDict。这使得该类与文档和 WSGIRequest 保持一致。
  • 添加了 HttpResponse.charset 属性。
  • WSGIRequestHandler 现在按照 RFC 将 URI 转换为 IRI,使用 uri_to_iri()
  • HttpRequest.get_full_path() 方法现在正确地对 Uniform Resource Identifier (URI) 的路径部分进行了字符转义,以防止不安全字符的问题。
  • HttpResponse 类现在实现了一些额外的方法,如 getvalue(),使得实例可以作为流对象使用。
  • 新的 HttpResponse.setdefault() 方法允许在尚未设置时设置标头。
  • 你可以使用新的 FileResponse 来流式传输文件。
  • 用于条件视图处理的 condition() 装饰器现在支持 If-unmodified-since 标头。

测试

验证器

  • URLValidator 现在支持 IPv6 地址、Unicode 域名和包含身份验证数据的 URL。

1.8 版本中的向后不兼容的更改

警告

除了本节中概述的更改之外,请确保查看 弃用计划,以了解已移除的任何功能。如果您在给定功能的弃用时间内未更新您的代码,其移除可能会被视为不兼容的变更。

将未保存的对象分配给关系会引发错误。

备注

为了更容易允许在内存中使用模型,这个更改在 Django 1.8.4 中已被撤销,并在 model.save() 期间替换为检查。例如:

>>> book = Book.objects.create(name="Django")
>>> book.author = Author(name="John")
>>> book.save()
Traceback (most recent call last):
...
ValueError: save() prohibited to prevent data loss due to unsaved related object 'author'.

在 Django 1.8.5 中,取消了对反向一对一关系分配的类似检查。

将未保存的对象分配给 ForeignKeyGenericForeignKeyOneToOneField 现在会引发 ValueError

以前,对未保存的对象的分配会被静默忽略。例如:

>>> book = Book.objects.create(name="Django")
>>> book.author = Author(name="John")
>>> book.author.save()
>>> book.save()

>>> Book.objects.get(name="Django")
>>> book.author
>>>

现在,将引发一个错误以防止数据丢失:

>>> book.author = Author(name="john")
Traceback (most recent call last):
...
ValueError: Cannot assign "<Author: John>": "Author" instance isn't saved in the database.

如果你需要允许分配未保存的实例(旧行为)并且不担心可能的数据丢失(例如,你从不将对象保存到数据库),你可以通过使用 ForeignKey.allow_unsaved_instance_assignment 属性来禁用此检查(此属性在 1.8.4 中已被移除,因为不再相关)。

仅接受位置参数的管理命令

如果你编写了一个只接受位置参数的自定义管理命令,并且没有指定 args 命令变量,你可能会遇到类似 Error: unrecognized arguments: ... 的错误,因为变量解析现在基于 argparse,它不会隐式接受位置参数。你可以通过简单地设置 args 类变量来使你的命令向后兼容。然而,如果你不需要与旧版本的 Django 保持兼容性,最好按照 编写自定义 django-admin 命令 中描述的方法实现新的 add_arguments() 方法。

通过测试运行器对自定义测试管理命令的参数进行设置

通过测试运行器向 test 管理命令添加自定义参数的方法已经发生了变化。以前,你可以在测试运行器上提供一个 option_list 类变量来添加更多参数(类似于 optparse)。现在,为了实现相同的行为,你必须在测试运行器上创建一个 add_arguments(cls, parser) 类方法,并调用 parser.add_argument 来添加任何自定义参数,因为现在的 parser 是一个 argparse.ArgumentParser 实例。

模型检查确保自动生成的列名在数据库指定的限制范围内

字段名长度超过数据库支持的列名长度可能会引发问题。例如,在 MySQL 中,尝试创建该列时会引发异常;在 PostgreSQL 中,数据库会截断列名(你可能会在 PostgreSQL 日志中看到警告)。

引入了模型检查,以在实际创建数据库表之前更好地提醒用户注意这种情况。

如果你有一个现有的模型,在其中这个检查似乎是一个错误的正检,例如在 PostgreSQL 上,其中名称已经被截断,只需使用 db_column 来指定正在使用的名称。

这个检查也适用于隐式生成的 ManyToManyField.through 模型中的列。如果在那里遇到问题,可以使用 through 创建一个显式模型,然后根据需要指定其列的 db_column

现在查询关系查找会检查对象类型

现在,查询模型查找会检查传递的对象是否是正确的类型,如果不是,则引发 ValueError。以前,Django 不关心对象是否是正确的类型;它只是使用对象的相关字段属性(例如 id)进行查找。现在,会引发错误以防止不正确的查找:

>>> book = Book.objects.create(name="Django")
>>> book = Book.objects.filter(author=book)
Traceback (most recent call last):
...
ValueError: Cannot query "<Book: Django>": Must be "Author" instance.

默认的 EmailField.max_length 增加到了 254。

旧的默认值为 75 个字符的 max_length 无法存储所有可能符合 RFC3696/5321 标准的电子邮件地址。为了存储所有可能的有效电子邮件地址,max_length 已增加到 254 个字符。您需要为受影响的模型生成并应用数据库迁移(或者如果希望保留当前字段的长度,则添加 max_length=75)。一个用于 django.contrib.auth.models.User.email 的迁移已包含在内。

对于早于 9.0 版本的 PostgreSQL 的支持

PostgreSQL 8.4 的上游支持期限在 2014 年 7 月结束。因此,Django 1.8 将 9.0 版本设置为其正式支持的最低 PostgreSQL 版本。

这还包括不再支持 PostGIS 1.3 和 1.4,因为这些版本在 8.4 之后的 PostgreSQL 版本上不受支持。

Django 现在要求使用 Psycopg2 版本 2.4.5 或更高版本(如果要使用 django.contrib.postgres,则需要 2.5+)。

对于早于 5.5 版本的 MySQL 的支持

MySQL 5.0 的上游支持期限在 2012 年 1 月到期,MySQL 5.1 的上游支持期限在 2013 年 12 月到期。因此,Django 1.8 将 5.5 版本设置为其正式支持的最低 MySQL 版本。

对于早于 11.1 版本的 Oracle 的支持

Oracle 9.2 的上游支持期限在 2010 年 7 月到期,Oracle 10.1 的上游支持期限在 2012 年 1 月到期,Oracle 10.2 的上游支持期限在 2013 年 7 月到期。因此,Django 1.8 将 11.1 版本设置为其正式支持的最低 Oracle 版本。

在 Oracle 上,测试中使用特定权限而不是角色。

早期版本的 Django 在 Oracle 上为测试用户授予 CONNECT 和 RESOURCE 角色。这些角色已被弃用,因此 Django 1.8 改为使用特定的底层权限。这改变了运行测试所需的主用户的权限(除非项目配置为避免创建测试用户)。现在所需的确切权限详见 Oracle 注释

AbstractUser.last_login 允许空值

AbstractUser.last_login 字段现在允许空值。以前,它默认为用户创建时的时间,如果用户从未登录,这会产生误导。如果你使用的是默认用户(django.contrib.auth.models.User),请运行 contrib.auth 中包含的数据库迁移。

如果你使用从 AbstractUser 继承的自定义用户模型,你需要运行 makemigrations 并为包含该模型的应用程序生成一个迁移。此外,如果希望将未登录的用户的 last_login 设置为 NULL,你可以运行以下查询:

from django.db import models
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractBaseUser

UserModel = get_user_model()
if issubclass(UserModel, AbstractBaseUser):
    UserModel._default_manager.filter(last_login=models.F("date_joined")).update(
        last_login=None
    )

django.contrib.gis

  • 不再支持 GEOS 3.1 和 GDAL 1.6 版本。
  • 不再支持 SpatiaLite 版本低于 2.4 。
  • GIS-specific lookups 已经重构以使用 django.db.models.Lookup API。
  • GEOSGeometry 对象的默认 str 表示已从 WKT 更改为 EWKT 格式(包括 SRID)。由于这个表示法在序列化框架中使用,这意味着 dumpdata 输出现在将包含几何对象的 SRID 值。

对于 TemplateResponse,上下文处理器的优先级已与 render 保持一致。

TemplateResponse 构造函数旨在成为 render() 函数的一个替代。然而,它存在一个轻微的不兼容性,即对于 TemplateResponse,传递的上下文字典中的上下文数据可能会被上下文处理器返回的上下文数据覆盖,而对于 render 则相反。这是一个错误,而 render 的行为更为合适,因为它允许在视图中本地覆盖全局定义的上下文处理器。如果你依赖于在 TemplateResponse 中使用上下文处理器可以覆盖上下文数据的事实,那么你需要更改你的代码。

在测试用例中重写 setUpClass / tearDownClass

装饰器 override_settings()modify_settings() 现在在作为类装饰器使用时以类级别的方式起作用。因此,在重写 setUpClass()tearDownClass() 时,应始终调用 super 实现。

移除了 django.contrib.formtools 模块

formtools contrib 应用已被移动到一个单独的包中,并相应的文档页面已被更新或删除。

新的包可以在 GitHub 和 PyPI 上获得。

测试之间重新加载数据库连接。

以前,在 TestCase 中的每个测试之间,Django 会关闭数据库连接。现在不再是这样了,因为 Django 现在会将整个 TestCase 包装在一个事务中。如果你的一些测试依赖于旧的行为,你应该让它们继承自 TransactionTestCase

django.template 命名空间进行了清理

如果你一直依赖于在 django.template 模块中公开的私有 API,你可能需要从 django.template.base 中导入它们。

另外,已删除了私有 API django.template.base.compile_string(), django.template.loader.find_template()django.template.loader.get_template_from_string()

私有模型关系上的 model 属性

在早期版本的 Django 中,对于具有反向外键关系的模型(例如),model._meta.get_all_related_objects() 返回关系作为具有 model 属性设置为关系源的 django.db.models.related.RelatedObject。现在,这个方法返回关系作为 django.db.models.fields.related.ManyToOneRel (私有 API RelatedObject 已被删除),并且 model 属性设置为关系目标而不是源。源模型可以在 related_model 属性上访问。

考虑一下来自 Django 1.8 教程的这个例子:

>>> p = Poll.objects.get(pk=1)
>>> p._meta.get_all_related_objects()
[<ManyToOneRel: polls.choice>]
>>> p._meta.get_all_related_objects()[0].model
<class 'polls.models.Poll'>
>>> p._meta.get_all_related_objects()[0].related_model
<class 'polls.models.Choice'>

将其与旧版本的行为进行比较:

>>> p._meta.get_all_related_objects()
[<RelatedObject: polls:choice related to poll>]
>>> p._meta.get_all_related_objects()[0].model
<class 'polls.models.Choice'>

为了访问源模型,您可以使用以下模式的代码,该代码可以在 Django 1.8 和旧版本中都有效:

for relation in opts.get_all_related_objects():
    to_model = getattr(relation, "related_model", relation.model)

还请注意,get_all_related_objects() 在 1.8 中已被弃用。

数据库后端 API

以下对数据库后端 API 的更改已记录,以帮助那些编写第三方后端的人更新其代码:

  • BaseDatabaseXXX 类已经移动到 django.db.backends.base。请从新的位置导入它们:

    from django.db.backends.base.base import BaseDatabaseWrapper
    from django.db.backends.base.client import BaseDatabaseClient
    from django.db.backends.base.creation import BaseDatabaseCreation
    from django.db.backends.base.features import BaseDatabaseFeatures
    from django.db.backends.base.introspection import BaseDatabaseIntrospection
    from django.db.backends.base.introspection import FieldInfo, TableInfo
    from django.db.backends.base.operations import BaseDatabaseOperations
    from django.db.backends.base.schema import BaseDatabaseSchemaEditor
    from django.db.backends.base.validation import BaseDatabaseValidation
    
  • DatabaseCreation 类中的 data_typesdata_types_suffixdata_type_check_constraints 属性已经移到了 DatabaseWrapper 中。

  • SQLCompiler.as_sql() 方法现在接受一个 subquery 参数 (#24164)。

  • BaseDatabaseOperations.date_interval_sql() 方法现在只接受一个 timedelta 参数。

django.contrib.admin

  • AdminSite 不再接受一个 app_name 参数,并且它的 app_name 属性已被删除。应用程序名称始终为 admin (与实例名称不同,你仍然可以使用 AdminSite(name="...") 进行自定义)。
  • ModelAdmin.get_object() 方法(私有 API)现在接受一个名为 from_field 的第三个参数,以指定应该与提供的 object_id 匹配的字段。
  • ModelAdmin.response_delete() 方法现在接受一个名为 obj_id 的第二个参数,它是在删除之前用于检索对象的序列化标识符。

默认情况下,django.template.defaultfilters 中的函数现在会自动进行自动转义。

为了在 Python 代码中调用输出 HTML 的内置模板过滤器时使其 "默认安全",已更改了 django.template.defaultfilters 中以下函数,以自动转义其输入值:

  • join
  • linebreaksbr
  • linebreaks_filter
  • linenumbers
  • unordered_list
  • urlize
  • urlizetrunc

如果您传递了可信内容,可以通过指定 autoescape=False 来恢复到旧的行为。在模板中使用相应的过滤器时,此更改不会产生任何效果。

杂项

  • connections.queries 现在是一个只读属性。

  • 现在只有当数据库连接是同一个对象时才被视为相等。它们不再是可哈希的。

  • GZipMiddleware 用于在请求来自 Internet Explorer 时禁用某些内容类型的压缩,以解决 IE6 及更早版本中的一个错误。这种行为可能会影响 IE7 及更高版本的性能。已被移除。

  • URLField.to_python 不再在没有路径的 URL 中添加尾随斜杠。

  • 模板过滤器 length 现在对未定义的变量返回 0,而不是空字符串。

  • ForeignKey.default_error_message['invalid'] 已从 '%(model)s instance with pk %(pk)r does not exist.' 更改为 '%(model)s instance with %(field)s %(value)r does not exist.' 如果您在自己的代码中使用此消息,请更新插入的参数列表。在内部,Django 将继续提供 params 中的 pk 参数以保持向后兼容性。

  • UserCreationForm.error_messages['duplicate_username'] 不再使用。如果您希望自定义该错误消息,请在表单上使用 Meta.error_messages['username'] 中的 'unique'覆盖它,或者如果您有一个自定义的 'username' 字段,可以在其 error_messages 参数中使用 'unique' 键。

  • django.contrib.adminbase.html 模板中,块 usertools 现在需要设置 has_permission 上下文变量。如果您有任何使用此模板的自定义管理视图,请更新它们以传递 AdminSite.has_permission() 作为这个新变量的值,或者简单地在上下文中包括 AdminSite.each_context(request)

  • ClearableFileInput 小部件进行了内部更改,以允许更多自定义。未记录的 url_markup_template 属性已被删除,而改用 template_with_initial

  • 为了与其他主要供应商保持一致,en_GB 区域现在将星期一作为一周的第一天。

  • TIME_FORMATDATETIME_FORMATSHORT_DATETIME_FORMAT 中,已从任何具有秒钟的区域中删除了秒钟。

  • Oracle 测试表空间的默认最大大小从 300M(或在 1.7.2 之前的 200M)增加到 500M 。

  • reverse()reverse_lazy() 现在返回 Unicode 字符串而不是字节字符串。

  • 所有缓存后端都已删除 CacheClass 部分。这些别名是为了向后兼容 Django 1.3 提供的。如果您仍在使用它们,请更新您的项目以使用在 CACHES 设置的 BACKEND 键中找到的真实类名。

  • 默认情况下,call_command() 现在总是跳过检查框架(除非您传递 skip_checks=False)。

  • 在迭代行时,File 现在使用 universal newlines。以下内容被识别为结束行:Unix 换行约定 '\n',Windows 换行约定 '\r\n' 和旧的 Macintosh 换行约定 '\r'

  • 如果 set() 失败,Memcached 缓存后端 MemcachedCachePyLibMCCache 将删除一个键。这是为了确保 cache_db 会话存储始终获取最新的会话数据。

  • django.test.utils 中删除了私有 API override_template_loadersoverride_with_test_loader。请改用 override_settings 来覆盖 TEMPLATES

  • DEBUG 设置为 True 时,MySQL 数据库后端不再将警告转换为异常。

  • HttpRequest 现在具有简化的 repr (例如 <WSGIRequest: GET '/somepath/'>)。这不会改变 SafeExceptionReporterFilter 类的行为。

  • 使用 ModelFormMixin 的类视图在同时指定 fieldsform_class 属性时将引发 ImproperlyConfigured 异常。以前,fields 会被静默忽略。

  • 在跟随重定向时,测试客户端现在会引发 RedirectCycleError,如果检测到循环或达到了最大重定向限制(而不是静默传递)。

  • 作为字段的 default 参数设置的可翻译字符串稍后会转换为具体的字符串,因此在某些情况下,Field.get_default() 的返回类型会有所不同。对于可调用返回的默认值没有变化。

  • GenericIPAddressField.empty_strings_allowed 现在是 False。将空字符串解释为 null 值的数据库后端(Django 包括的后端中只有 Oracle)将不再将 null 值转换回空字符串。这与其他后端保持一致。

  • BaseCommand.leave_locale_alone 属性为 False 时,现在会停用翻译,而不是强制使用 "en-us" 区域设置。如果您的模型包含非英语字符串,并且您依赖于在管理命令中激活英语翻译,那么这将不再发生。可能会在迁移到 1.8 后生成新的数据库迁移(一次)。

  • 当翻译被临时停用时,django.utils.translation.get_language() 现在返回 None 而不是 LANGUAGE_CODE

  • 当不存在特定文字的翻译时,现在会从 LANGUAGE_CODE 语言中获取回退翻译(而不是从未翻译的 msgid 消息中获取)。

  • django.contrib.contenttypes.models.ContentTypename 字段已经在迁移中删除,并被一个属性替代。这意味着不再可以使用这个字段来查询或过滤 ContentType 了。

    如果你升级到 Django 1.8 并跳过了 Django 1.7,请注意。如果你运行 manage.py migrate --fake,这个迁移将被跳过,并且你会看到一个 RuntimeError: Error creating new content types. 异常,因为 name 列不会从数据库中删除。使用 manage.py migrate --fake-initial 仅虚拟执行初始迁移。

  • 新的 migrate --fake-initial 选项允许虚拟执行初始迁移。在 1.7 版中,如果初始迁移中创建的所有表格已经存在,初始迁移将始终自动虚拟执行。

  • 一个没有迁移的应用程序,其内含一个对有迁移的应用程序的 ForeignKey,在迁移数据库或运行测试时可能会导致外键约束错误。在 Django 1.7 中,这可能会导致默默失败并导致约束丢失。要解决这个错误,请为没有迁移的应用程序添加迁移。

在 1.8 中被废弃的功能

django.db.models.options.Options 中的选定方法

作为正式化 Model._meta API(来自 django.db.models.options.Options 类)的一部分,一些方法已被弃用,并将在 Django 1.10 中移除:

  • get_all_field_names()
  • get_all_related_objects()
  • get_all_related_objects_with_model()
  • get_all_related_many_to_many_objects()
  • get_all_related_m2m_objects_with_model()
  • get_concrete_fields_with_model()
  • get_field_by_name()
  • get_fields_with_model()
  • get_m2m_with_model()

加载 cyclefirstof 模板标签来自 future

Django 1.6 引入了 {% load cycle from future %}{% load firstof from future %} 语法,用于前向兼容 cyclefirstof 模板标签。此语法现已被弃用,并将在 Django 1.10 中移除。您可以简单地删除 {% load ... from future %} 标签。

django.conf.urls.patterns()

在早期的 Django 中,鼓励在 urlpatterns 中将视图引用为字符串:

urlpatterns = patterns(
    "",
    url("^$", "myapp.views.myview"),
)

Django 会在内部神奇地导入 myapp.views.myview 并将字符串转换为真实的函数引用。为了减少在引用同一模块中的多个视图时的重复性,patterns() 函数接受一个必需的初始 prefix 参数,该参数会添加到该组 urlpatterns 中所有作为字符串的视图前面:

urlpatterns = patterns(
    "myapp.views",
    url("^$", "myview"),
    url("^other/$", "otherview"),
)

在现代时代,我们已经更新了教程,建议导入您的视图模块并直接引用您的视图函数(或类)。这样做有很多优点,所有优点都源自于我们使用普通的 Python 代替“Django 字符串魔法”:当您拼写错误视图名称时的错误更不隐晦,集成开发环境可以帮助自动完成视图名称等等。

因此,现在更有可能以以下方式编写(也更好地编写)上述使用 prefix 参数的代码:

from myapp import views

urlpatterns = patterns(
    "",
    url("^$", views.myview),
    url("^other/$", views.otherview),
)

因此,patterns() 函数的作用很小,并且在教新用户时会造成困扰(回答新手的问题 "为什么我需要将空字符串作为 patterns() 的第一个参数?")。出于这些原因,我们正在弃用它。更新您的代码非常简单,只需确保 urlpatternsdjango.conf.urls.url() 实例的列表。例如:

from django.conf.urls import url
from myapp import views

urlpatterns = [
    url("^$", views.myview),
    url("^other/$", views.otherview),
]

将字符串作为 view 传递给 django.conf.urls.url()

与前面的项目相关,将视图作为字符串引用在 url() 函数中已被弃用。请按照前面的部分所描述的方式传递可调用的视图函数。

django.core.context_processors

内置模板上下文处理器已经移动到 django.template.context_processors

django.test.SimpleTestCase.urls

用于在测试中指定 URLconf 配置的属性 SimpleTestCase.urls 已被弃用,并将在 Django 1.10 中移除。请改用 @override_settings(ROOT_URLCONF=...)

prefix 参数用于 i18n_patterns() 函数。

与前面的项目相关,已弃用了 django.conf.urls.i18n.i18n_patterns() 函数的 prefix 参数。只需传递一个 django.conf.urls.url() 实例的列表即可。

for 模板标签中使用错误的解包值数量

在 Django 1.10 中,在 for 标签中使用错误的解包值数量将引发异常,而不是静默失败。

传递点路径给 reverse()url

通过 Python 路径反向解析 URL 是一项昂贵的操作,因为它导致被反向解析的路径被导入。这种行为还导致了一个 security issue。请改用 命名的 URL 模式 来进行反向解析。

如果您正在使用 django.contrib.sitemaps,请在引用 django.contrib.sitemaps.views.sitemap()url 中添加 name 参数:

from django.contrib.sitemaps.views import sitemap

url(
    r"^sitemap\.xml$",
    sitemap,
    {"sitemaps": sitemaps},
    name="django.contrib.sitemaps.views.sitemap",
)

为了确保在 Django 1.10 中移除通过 Python 路径进行反向解析时的兼容性。

同样对于 GIS 网站地图,添加 name='django.contrib.gis.sitemaps.views.kml'name='django.contrib.gis.sitemaps.views.kmz'

如果您正在为 LOGIN_URLLOGIN_REDIRECT_URL 设置使用 Python 路径,请改为使用 url() 的名称。

聚合方法和模块

django.db.models.sql.aggregatesdjango.contrib.gis.db.models.sql.aggregates 模块(都是私有 API)已被弃用,因为 django.db.models.aggregatesdjango.contrib.gis.db.models.aggregates 现在也负责 SQL 生成。旧模块将在 Django 1.10 中移除。

如果您正在使用旧模块,请参阅 查询表达式,以了解如何使用新的稳定 API 重写自定义聚合函数。

以下方法和属性已经被弃用,并且在 Django 1.10 中将移除与向后兼容的包装:

  • Query.aggregates,已被替换为 annotations
  • Query.aggregate_select,已被替换为 annotation_select
  • Query.add_aggregate(),已被替换为 add_annotation()
  • Query.set_aggregate_mask(),已被替换为 set_annotation_mask()
  • Query.append_aggregate_mask(),已被替换为 append_annotation_mask()

通过 Command.option_list 扩展管理命令参数

管理命令现在使用 argparse 而不是 optparse 来解析传递给命令的命令行参数。这也意味着添加自定义参数到命令的方式已经改变:不再扩展 option_list 类列表,而是现在应该覆盖 add_arguments() 方法,并通过 argparse.add_argument() 添加参数。有关更多详细信息,请参阅 此示例

django.core.management.NoArgsCommand

NoArgsCommand 现已被弃用,将在 Django 1.10 中移除。请改用 BaseCommand,默认情况下不接受参数。

列出项目中的所有迁移

migrate 管理命令的 --list 选项已被弃用,将在 Django 1.10 中移除。请改用 showmigrations

ModelChoiceFieldModelMultipleChoiceFieldcache_choices 选项

ModelChoiceFieldModelMultipleChoiceField 接受了一个未记录和未经测试的选项 cache_choices。该选项在同一 Form 对象的多次渲染之间缓存了查询集。该选项将加速弃用,并将在 Django 1.9 中移除。

django.template.resolve_variable()

这个函数已经在一段时间内非正式地标记为 "弃用"。请使用 django.template.Variable(path).resolve(context) 替代 resolve_variable(path, context)

django.contrib.webdesign

它提供了 lorem 模板标签,现在已包含在内置标签中。只需从 INSTALLED_APPS 中移除 'django.contrib.webdesign',并从您的模板中移除 {% load webdesign %}

django.forms.RegexFielderror_message 参数已被弃用

它提供了对 1.0 版本之前的代码的向后兼容性,但其功能是多余的。请改用 Field.error_messages['invalid']

旧的 unordered_list 语法

已弃用了 unordered_list 模板过滤器的旧输入格式,这是一个较旧(1.0 版本之前)的、更受限制和冗长的格式:

["States", [["Kansas", [["Lawrence", []], ["Topeka", []]]], ["Illinois", []]]]

使用新的语法,这将变为:

["States", ["Kansas", ["Lawrence", "Topeka"], "Illinois"]]

django.forms.Field._has_changed()

将这个方法的名称更改为 has_changed(),删除前导的下划线。旧的名称将在 Django 1.10 之前仍然有效。

django.utils.html.remove_tags()removetags 模板过滤器

django.utils.html.remove_tags() 以及模板过滤器 removetags 已被弃用,因为它们无法保证安全的输出。它们的存在可能会导致在安全敏感的上下文中使用它们,而实际上它们并不安全。

未使用且未记录的 django.utils.html.strip_entities() 函数也已被弃用。

django.contrib.auth.views.password_reset()is_admin_site 参数

这是一个遗留选项,应该不再需要。

SubfieldBase

django.db.models.fields.subclassing.SubfieldBase 已被弃用,并将在 Django 1.10 中删除。从历史上看,它用于处理需要在从数据库加载时进行类型转换的字段,但在 .values() 调用或聚合中不使用。它已被 from_db_value() 替代。

新的方法在赋值时不会调用 to_python() 方法,就像 SubfieldBase 的情况一样。如果你需要这个行为,请在你的项目中重新实现 Creator 类,可以从 Django 的源代码中获取 链接

django.utils.checksums

django.utils.checksums 模块已被弃用,并将在 Django 1.10 中删除。它提供的功能(使用 Luhn 算法验证校验和)未经文档化,并且在 Django 中未被使用。该模块已被移动到 django-localflavor 包中(版本 1.1+)。

InlineAdminForm.original_content_type_id

InlineAdminForm 上的 original_content_type_id 属性已被弃用,并将在 Django 1.10 中删除。从历史上看,它用于构建“查看网站上的内容” URL。现在可以使用表单的 absolute_url 属性访问此 URL。

django.views.generic.edit.FormMixin.get_form() 方法的 form_class 参数

FormMixin 的子类在重写 get_form() 方法时,应确保为 form_class 参数提供默认值,因为它现在是可选的。

使用 get_template() 加载的模板进行渲染,需要使用 Context

在 Django 1.8 中,get_template() 的返回类型已更改:不再返回 django.template.Template,而是返回一个 Template 实例,其确切类型取决于加载它的后端。

这两个类都提供了一个 render() 方法,然而,前者接受一个 django.template.Context 作为参数,而后者期望一个 dict。这个更改是通过 Django 模板的弃用路径来强制执行的。

所有这些也适用于 select_template()

在模板响应中使用 TemplateContext 类。

SimpleTemplateResponseTemplateResponse 的一些方法以前接受 django.template.Contextdjango.template.Template 对象作为参数。现在它们应该分别接收 dict 和依赖于后端的模板对象。

如果您已经对模板响应类进行了子类化,这也适用于返回类型。

请查看 模板响应 API 文档 获取详细信息。

渲染函数的 dictionarycontext_instance 参数

在 Django 1.10 中,以下函数将不再接受 dictionarycontext_instance 参数:

  • django.shortcuts.render()
  • django.shortcuts.render_to_response()
  • django.template.loader.render_to_string()

请改用 context 参数。当 dictionary 作为位置参数传递时,这是最常见的用法,无需进行更改。

如果在 context_instance 中传递了 Context,请在 context 参数中传递一个 dict。如果传递了 RequestContext,请在 request 参数中单独传递请求。

模板查找函数的 dirs 参数

在 Django 1.10 中,以下函数将不再接受 dirs 参数来覆盖 TEMPLATE_DIRS

该参数在不同的模板加载器之间不一致,并且在包含的模板中无法正常工作。

django.template.loader.BaseLoader

django.template.loader.BaseLoader 已更名为 django.template.loaders.base.Loader。如果您编写了一个自定义的模板加载器,继承自 BaseLoader,那么您必须改为继承 Loader

django.test.utils.TestTemplateLoader

私有 API django.test.utils.TestTemplateLoader 已弃用,推荐使用 django.template.loaders.locmem.Loader,将在 Django 1.9 中移除。

自定义 Storage 类上 max_length 参数的支持

如果自定义的 Storage 子类重写了 get_available_name() 和/或 save() 方法,应该将 max_length=None 添加为参数。不接受这个参数的存储支持将在 Django 1.10 中移除。

qn 被替换为 compiler

在以前的 Django 版本中,各种内部的 ORM 方法(主要是 as_sql 方法)接受一个名为 qn (代表 "quote name")的参数,它是一个引用了一个函数来为发送到数据库的标识符加引号的参数。在 Django 1.8 中,这个参数已被重命名为 compiler,并且现在是一个完整的 SQLCompiler 实例。为了向后兼容,调用一个 SQLCompiler 实例执行与之前 qn 函数相同的名称引用操作。然而,这个向后兼容性的支持被立即弃用:您应该将您的 qn 参数重命名为 compiler,并在以前调用 qn(...) 的地方改为调用 compiler.quote_name_unless_alias(...)

RedirectView.permanent 的默认值

RedirectView.permanent 属性的默认值将在 Django 1.9 中从 True 更改为 False

在没有使用 SessionAuthenticationMiddleware 的情况下使用 AuthenticationMiddleware

django.contrib.auth.middleware.SessionAuthenticationMiddleware 是在 Django 1.7 中添加的。在 Django 1.7.2 中,它的功能被移动到了 auth.get_user() 中,并且为了向后兼容,只有在 MIDDLEWARE_CLASSES 中出现 'django.contrib.auth.middleware.SessionAuthenticationMiddleware' 才会启用它。

在 Django 1.10 中,无论是否启用 SessionAuthenticationMiddleware,会启用会话验证(此时 SessionAuthenticationMiddleware 将不再具有重要意义)。您可以在那之前的某个时候将其添加到您的 MIDDLEWARE_CLASSES 中以选择启用它。请首先阅读 升级注意事项

django.contrib.sitemaps.FlatPageSitemap

django.contrib.sitemaps.FlatPageSitemap 已经移动到 django.contrib.flatpages.sitemaps.FlatPageSitemap。旧的导入位置已被弃用,并将在 Django 1.9 中移除。

ssi 模板标签

ssi 模板标签允许通过绝对路径将文件包含到模板中。在大多数部署情况下,这具有有限的用途,通常更有意义的是使用 include 标签。此标签现在已被弃用,并将在 Django 1.10 中移除。

if 模板标签中的比较运算符 = 已被弃用

{% if %} 模板标签中使用单个等号进行相等性测试是未记录和未经测试的。现在已弃用,建议使用 ==

ModelFormMixin.success_url 中使用的 %(<foo>)s 语法已被弃用

ModelFormMixin.success_url 中的遗留 %(<foo>)s 语法已被弃用,并将在 Django 1.10 中移除。

GeoQuerySet 聚合方法

collect(), extent(), extent3d(), make_line(), 和 unionagg() 聚合方法已被弃用,应该用它们的基于函数的聚合等效方法(CollectExtentExtent3DMakeLineUnion)来替代。

allow_migrate 路由方法的签名

数据库路由器的 allow_migrate() 方法的签名已从 allow_migrate(db, model) 更改为 allow_migrate(db, app_label, model_name=None, **hints)

当设置了 model_name 时,之前通过 model 位置参数传递的值现在可以在 hints 字典中的键 'model' 下找到。

在切换到新签名后,路由器还将被 RunPythonRunSQL 操作调用。

在 1.8 版本中移除的功能

这些特性已经到达了它们的弃用周期的尽头,并在 Django 1.8 中被移除。有关详细信息,包括如何删除对这些特性的使用,请参阅 在 1.6 中被废弃的功能

  • django.contrib.comments 已被移除。
  • 以下事务管理 API 已被移除:
    • TransactionMiddleware
    • django.db.transaction 中定义的装饰器和上下文管理器 autocommit, commit_on_success, 和 commit_manually 已被移除。
    • django.db.transaction 中定义的函数 commit_unless_managedrollback_unless_managed 也已被移除。
    • TRANSACTIONS_MANAGED 设置
  • cyclefirstof 模板标签会自动转义其参数。
  • SEND_BROKEN_LINK_EMAILS 设置已被移除。
  • django.middleware.doc.XViewMiddleware 已被移除。
  • Model._meta.module_name 别名已被移除。
  • 已经移除了为了重命名 get_query_set 和类似的查询集方法而引入的向后兼容的包装。这会影响以下类:BaseModelAdminChangeListBaseCommentNodeGenericForeignKeyManagerSingleRelatedObjectDescriptorReverseSingleRelatedObjectDescriptor
  • 已经移除了为了重命名属性 ChangeList.root_query_setChangeList.query_set 而引入的向后兼容的包装。
  • django.views.defaults.shortcutdjango.conf.urls.shortcut 已被移除。
  • 不再支持 Python Imaging Library (PIL) 模块。
  • 以下私有 API 已被移除:
    • django.db.backend
    • django.db.close_connection()
    • django.db.backends.creation.BaseDatabaseCreation.set_autocommit()
    • django.db.transaction.is_managed()
    • django.db.transaction.managed()
  • django.forms.widgets.RadioInput 已被移除。
  • 模块 django.test.simple 和类 django.test.simple.DjangoTestSuiteRunner 已被移除。
  • 模块 django.test._doctest 已被移除。
  • CACHE_MIDDLEWARE_ANONYMOUS_ONLY 设置已被移除。这个改变影响了 django.middleware.cache.CacheMiddlewaredjango.middleware.cache.UpdateCacheMiddleware,尽管在后者类中没有弃用警告。
  • Django 不再在模型或表单层面使用硬编码的字符串 Hold down "Control", or "Command" on a Mac, to select more than one. 来覆盖或附加到用户提供的 ManyToMany 模型字段的 help_text
  • Model._meta.get_(add|change|delete)_permission 方法已被移除。
  • 不再读取会话键 django_language 以保持向后兼容性。
  • 地理位置 Sitemaps 已被移除(django.contrib.gis.sitemaps.views.indexdjango.contrib.gis.sitemaps.views.sitemap)。
  • django.utils.html.fix_ampersandsfix_ampersands 模板过滤器以及 django.utils.html.clean_html 都已被移除。
Back to Top