# Django 5.2.8 documentation

# 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 特定的功能，例如 `ArrayField`、`HStoreField`、范围字段 和 `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` 逻辑。

还包括了一组 数据库函数，其中包括 `Coalesce`、`Concat` 和 `Substr` 等功能。

### `TestCase` 数据设置

`TestCase` has been refactored to allow for data initialization at the class level using transactions and savepoints. Database backends which do not support transactions, like MySQL with the MyISAM storage engine, will still be able to run these tests but won't benefit from the improvements. Tests are now run within two nested `atomic()` blocks: one for the whole class and one for each test.

- 类方法 `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`

- 授权后端现在可以在 `has_perm()` 和 `has_module_perms()` 中引发 `PermissionDenied` 以绕过权限检查。

- `PasswordResetForm` 现在有一个可以被重写以自定义要发送的邮件的方法 `send_mail()`。

- `Permission.name` 的 `max_length` 从 50 增加到 255 个字符。请运行数据库迁移。

- `USERNAME_FIELD` 和 `REQUIRED_FIELDS` 现在支持 `ForeignKey`。

- PBKDF2 密码哈希器的默认迭代次数增加了 33%。这个向后兼容的变更不会影响那些已经子类化了 `django.contrib.auth.hashers.PBKDF2PasswordHasher` 以更改默认值的用户。

#### `django.contrib.gis`

- 现在有一个新的 GeoJSON 序列化程序 可供使用。

- 现在允许将子查询作为地理查找参数，例如 `City.objects.filter(point__within=Country.objects.filter(continent='Africa').values('mpoly'))`。

- 当数据库版本为 3.0 或更高时，SpatiaLite 后端现在支持 `Collect` 和 `Extent` 聚合函数。

- PostGIS 2 中的 `CREATE EXTENSION postgis` 和 SpatiaLite 中的 `SELECT InitSpatialMetaData` 初始化命令现在会被 `migrate` 自动执行。

- GDAL 接口现在支持检索 栅格（图像）数据文件 的属性。

- 已删除了 Django 1.2 中更改的 `SpatialRefSys` 和 `GeometryColumns` 的兼容性 shims。

- 现在所有与 GDAL 相关的异常都使用 `GDALException` 引发。以前的 `OGRException` 已保留以保持向后兼容性，但不应再使用。

#### `django.contrib.sessions`

- Session cookie is now deleted after `flush()` is called.

#### `django.contrib.sitemaps`

- 新的 `Sitemap.i18n` 属性允许你基于 `LANGUAGES` 设置生成多语言站点地图。

#### `django.contrib.sites`

- 如果没有定义 `SITE_ID` 设置，`get_current_site()` 现在将基于 `request.get_host()` 查找当前站点。

- 在运行 `migrate` 时创建的默认 `Site` 现在会遵循 `SITE_ID` 设置（而不是总是使用 `pk=1`）。

#### 缓存

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

#### 密码学

- The `max_age` parameter of the `django.core.signing.TimestampSigner.unsign()` method now also accepts a `datetime.timedelta` object.

#### 数据库后端

- 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 现在在获取表的描述时将包括一个缓存破坏子句。

#### 电子邮件

- 电子邮件后端 现在支持上下文管理协议，用于打开和关闭连接。

- SMTP 电子邮件后端现在支持使用 `EMAIL_SSL_CERTFILE` 和 `EMAIL_SSL_KEYFILE` 设置进行 `keyfile` 和 `certfile` 身份验证。

- SMTP `EmailBackend` 现在支持使用 `EMAIL_TIMEOUT` 设置来设置 `timeout` 参数。

- `EmailMessage` 和 `EmailMultiAlternatives` 现在支持 `reply_to` 参数。

#### 文件存储

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

#### 表单

- 表单小部件现在将值为 `True` 或 `False` 的属性呈现为 HTML5 布尔属性。

- The new `has_error()` method allows checking if a specific error has happened.

- 如果在表单上定义了 `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` 时可以传递一个可调用对象，该可调用对象返回一个选项的可迭代对象。

#### 通用视图

- Generic views that use `MultipleObjectMixin` may now specify the ordering applied to the `queryset` by setting `ordering` or overriding `get_ordering()`.

- The new `SingleObjectMixin.query_pk_and_slug` attribute allows changing the behavior of `get_object()` so that it'll perform its lookup using both the primary key and the slug.

- The `get_form()` method doesn't require a `form_class` to be provided anymore. If not provided `form_class` defaults to `get_form_class()`.

- Placeholders in `ModelFormMixin.success_url` now support the Python `str.format()` syntax. The legacy `%(<foo>)s` syntax is still supported but will be removed in Django 1.10.

#### 国际化

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

#### 日志

- `django.utils.log.AdminEmailHandler` 类现在具有 `send_mail()` 方法，使其更容易进行子类化。

#### 管理命令

- 现在，从命令行调用的管理命令完成其工作后，数据库连接将始终关闭。

- 现在还可以发现来自诸如"eggs "之类的备用软件包格式的命令。

- 新的 `dumpdata --output` 选项允许指定将序列化数据写入的文件。

- 新的 `makemessages --exclude` 和 `compilemessages --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` 命令允许列出项目中的所有迁移及其依赖关系。

#### 中间件

- `CommonMiddleware.response_redirect_class` 属性允许您自定义中间件发出的重定向。

- 在 `DEBUG` 模式下，当中间件引发 `MiddlewareNotUsed` 异常时，将会在 `django.request` 记录器中记录调试消息。

#### 迁移

- `RunSQL` 操作现在可以处理传递给 SQL 语句的参数。

- 现在可以为没有模型的应用程序创建迁移（很可能是 数据迁移）。

- 迁移现在可以将模型管理器 序列化为模型状态 的一部分。

- 添加了一种 处理模型字段弃用的通用机制。

- 添加了 `RunPython.noop()` 和 `RunSQL.noop` 类方法/属性，以便于使 `RunPython` 和 `RunSQL` 操作可逆。

- 现在，迁移操作 `RunPython` 和 `RunSQL` 会调用数据库路由器的 `allow_migrate()` 方法。路由器可以使用新引入的 `app_label` 和 `hints` 参数来进行路由决策。要利用此功能，您需要将路由器更新到新的 `allow_migrate` 签名，有关详细信息，请参阅 弃用部分。

#### 模型

- 现在，Django 最多记录 9000 条查询在 `connections.queries` 中，以防止在调试模式下的长时间运行过程中出现过多的内存使用。

- 现在有一个模型 `Meta` 选项，可以为模型的所有关联字段定义 `默认相关名称`。

- 在不同版本的 Django 之间对模型和查询集进行 pickling 并不是官方支持的（它可能会工作，但没有保证）。现在，一个额外的变量被添加到模型和查询集的 pickled 状态中，用来指定当前的 Django 版本，当这些对象在与其被 pickled 的版本不同的版本中 unpickle 时，Django 会引发一个 `RuntimeWarning`。

- 添加了 `Model.from_db()`，Django 在使用 ORM 加载对象时会使用这个方法。该方法允许自定义模型的加载行为。

- 现在，`extra(select={...})` 允许您使用 `%%s` 来转义文本中的字面 `%s` 序列。

- 现在可以使用装饰器模式注册 自定义查找器。

- 新的 `Transform.bilateral` 属性允许创建双向变换。这些变换在查找表达式中同时应用于 `lhs` 和 `rhs`，提供了更多复杂查找的机会。

- 现在，当使用模式查找（例如 `contains`、`startswith` 等）与 `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()` 方法能够正确处理以 `//` 开头的路径。

- 如果 `DEBUG` 为 `True`，并且请求引发了 `SuspiciousOperation` 异常，将会使用详细的错误页面呈现响应。

- `QueryDict` 的 `query_string` 参数现在是可选的，默认值为 `None`，因此可以使用 `QueryDict()` 来实例化一个空的 `QueryDict`，而不是 `QueryDict(None)` 或 `QueryDict('')`。

- `HttpRequest` 对象的 `GET` 和 `POST` 属性现在是 `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` 标头。

#### 测试

- `RequestFactory.trace()` 和 `Client.trace()` 方法已经实现，允许你在测试中创建 `TRACE` 请求。

- `assertTemplateUsed()` 添加了 `count` 参数。这允许你断言模板被渲染了特定次数。

- 新的 `assertJSONNotEqual()` 断言允许你测试两个 JSON 片段不相等。

- 为 `test` 命令添加了选项，以保留测试数据库 (`--keepdb`)，以倒序运行测试用例 (`--reverse`)，并为失败的测试启用 SQL 日志记录 (`--debug-sql`)。

- 为测试客户端响应添加了 `resolver_match` 属性。

- 添加了一些设置，允许自定义 Oracle 测试表空间参数： `DATAFILE`、`DATAFILE_TMP`、`DATAFILE_MAXSIZE` 和 `DATAFILE_TMP_MAXSIZE`。

- `override_settings()` 装饰器现在可以影响 `DATABASE_ROUTERS` 中的主路由器。

- 添加了对使用类文件对象进行文件上传的测试客户端支持。

- 在使用 Python 3.4+ 和 SQLite 3.7.13+ 进行测试时，现在使用共享缓存来测试 SQLite 内存数据库。这允许在线程之间共享数据库。

#### 验证器

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

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

Warning

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

### 相关对象操作在事务中执行

Some operations on related objects such as `add()` or direct assignment ran multiple data modifying queries without wrapping them in transactions. To reduce the risk of data corruption, all data modifying methods that affect multiple related objects (i.e. `add()`, `remove()`, `clear()`, and direct assignment) now perform their data modifying queries from within a transaction, provided your database supports transactions.

这个改变带来了一个向后不兼容的副作用，从这些方法触发的信号处理程序现在在方法的事务中执行，而且信号处理程序中的任何异常都会阻止整个操作。

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

Note

为了更容易允许在内存中使用模型，这个更改在 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 中，取消了对反向一对一关系分配的类似检查。

将未保存的对象分配给 `ForeignKey`、`GenericForeignKey` 和 `OneToOneField` 现在会引发 `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 中已被移除，因为不再相关）。

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

If you have written a custom management command that only accepts positional arguments and you didn't specify the `args` command variable, you might get an error like `Error: unrecognized arguments: ...`, as variable parsing is now based on `argparse` which doesn't implicitly accept positional arguments. You can make your command backwards compatible by simply setting the `args` class variable. However, if you don't have to keep compatibility with older Django versions, it's better to implement the new `add_arguments()` method as described in 编写自定义 django-admin 命令.

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

The method to add custom arguments to the `test` management command through the test runner has changed. Previously, you could provide an `option_list` class variable on the test runner to add more arguments (à la `optparse`). Now to implement the same behavior, you have to create an `add_arguments(cls, parser)` class method on the test runner and call `parser.add_argument` to add any custom arguments, as parser is now an `argparse.ArgumentParser` instance.

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

字段名长度超过数据库支持的列名长度可能会引发问题。例如，在 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.

### `select_related()` 现在会检查给定的字段。

`select_related()` 现在会验证给定的字段是否实际存在。以前，不存在的字段会被默默忽略。现在会引发错误：

    >>> book = Book.objects.select_related("nonexistent_field")
    Traceback (most recent call last):
    ...
    FieldError: Invalid field name(s) given in select_related: 'nonexistent_field'

验证还确保给定字段是关系型的：

    >>> book = Book.objects.select_related("name")
    Traceback (most recent call last):
    ...
    FieldError: Non-relational field given in select_related: 'name'

### 默认的 `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_types`、`data_types_suffix` 和 `data_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.admin` 的 `base.html` 模板中，块 `usertools` 现在需要设置 `has_permission` 上下文变量。如果您有任何使用此模板的自定义管理视图，请更新它们以传递 `AdminSite.has_permission()` 作为这个新变量的值，或者简单地在上下文中包括 `AdminSite.each_context(request)`。

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

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

- 在 `TIME_FORMAT`、`DATETIME_FORMAT` 或 `SHORT_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 缓存后端 `MemcachedCache` 和 `PyLibMCCache` 将删除一个键。这是为了确保 `cache_db` 会话存储始终获取最新的会话数据。

- 在 `django.test.utils` 中删除了私有 API `override_template_loaders` 和 `override_with_test_loader`。请改用 `override_settings` 来覆盖 `TEMPLATES`。

- 当 `DEBUG` 设置为 `True` 时，MySQL 数据库后端不再将警告转换为异常。

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

- 使用 `ModelFormMixin` 的类视图在同时指定 `fields` 和 `form_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()` now returns `None` instead of `LANGUAGE_CODE` when translations are temporarily deactivated.

- 当不存在特定文字的翻译时，现在会从 `LANGUAGE_CODE` 语言中获取回退翻译（而不是从未翻译的 `msgid` 消息中获取）。

- `django.contrib.contenttypes.models.ContentType` 的 `name` 字段已经在迁移中删除，并被一个属性替代。这意味着不再可以使用这个字段来查询或过滤 `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()`

### 加载 `cycle` 和 `firstof` 模板标签来自 `future` 库

Django 1.6 引入了 `{% load cycle from future %}` 和 `{% load firstof from future %}` 语法，用于前向兼容 `cycle` 和 `firstof` 模板标签。此语法现已被弃用，并将在 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()` 的第一个参数？"）。出于这些原因，我们正在弃用它。更新您的代码非常简单，只需确保 `urlpatterns` 是 `django.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()` 函数中已被弃用。请按照前面的部分所描述的方式传递可调用的视图函数。

### 模板相关的设置

由于多个模板引擎的重构，一些设置已被弃用，建议使用 `TEMPLATES` 代替：

- `ALLOWED_INCLUDE_ROOTS`

- `TEMPLATE_CONTEXT_PROCESSORS`

- `TEMPLATE_DEBUG`

- `TEMPLATE_DIRS`

- `TEMPLATE_LOADERS`

- `TEMPLATE_STRING_IF_INVALID`

### `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_URL` 或 `LOGIN_REDIRECT_URL` 设置使用 Python 路径，请改为使用 `url()` 的名称。

### 聚合方法和模块

`django.db.models.sql.aggregates` 和 `django.contrib.gis.db.models.sql.aggregates` 模块（都是私有 API）已被弃用，因为 `django.db.models.aggregates` 和 `django.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` 扩展管理命令参数

Management commands now use `argparse` instead of `optparse` to parse command-line arguments passed to commands. This also means that the way to add custom arguments to commands has changed: instead of extending the `option_list` class list, you should now override the `add_arguments()` method and add arguments through `argparse.add_argument()`. See this example for more details.

### `django.core.management.NoArgsCommand`

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

### 列出项目中的所有迁移

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

### `ModelChoiceField` 和 `ModelMultipleChoiceField` 的 `cache_choices` 选项

`ModelChoiceField` 和 `ModelMultipleChoiceField` 接受了一个未记录和未经测试的选项 `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.RegexField` 的 `error_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` 参数提供默认值，因为它现在是可选的。

### Rendering templates loaded by `get_template()` with a `Context`

The return type of `get_template()` has changed in Django 1.8: instead of a `django.template.Template`, it returns a `Template` instance whose exact type depends on which backend loaded it.

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

All this also applies to `select_template()`.

### 在模板响应中使用 `Template` 和 `Context` 类。

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

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

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

### 与模板相关的 API 中的 `current_app` 参数

以下函数和类将不再接受 `current_app` 参数来设置 Django 1.10 中的 URL 命名空间：

- `django.shortcuts.render()`

- `django.template.Context()`

- `django.template.RequestContext()`

- `django.template.response.TemplateResponse()`

请设置 `request.current_app`，其中 `request` 是这些函数或类的第一个参数。如果你使用一个普通的 `Context`，请改用 `RequestContext`。

### 渲染函数的 `dictionary` 和 `context_instance` 参数

在 Django 1.10 中，以下函数将不再接受 `dictionary` 和 `context_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.get_template()`

- `django.template.loader.select_template()`

- `django.shortcuts.render()`

- `django.shortcuts.render_to_response()`

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

### `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 中移除。

### 模型 `Field.related`

Private attribute `django.db.models.Field.related` is deprecated in favor of `Field.rel`. The latter is an instance of `django.db.models.fields.related.ForeignObjectRel` which replaces `django.db.models.related.RelatedObject`. The `django.db.models.related` module has been removed and the `Field.related` attribute will be removed in Django 1.10.

### `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()` 聚合方法已被弃用，应该用它们的基于函数的聚合等效方法（`Collect`、`Extent`、`Extent3D`、`MakeLine` 和 `Union`）来替代。

### `allow_migrate` 路由方法的签名

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

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

在切换到新签名后，路由器还将被 `RunPython` 和 `RunSQL` 操作调用。

## 在 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_managed` 和 `rollback_unless_managed` 也已被移除。

  - `TRANSACTIONS_MANAGED` 设置

- `cycle` 和 `firstof` 模板标签会自动转义其参数。

- `SEND_BROKEN_LINK_EMAILS` 设置已被移除。

- `django.middleware.doc.XViewMiddleware` 已被移除。

- `Model._meta.module_name` 别名已被移除。

- 已经移除了为了重命名 `get_query_set` 和类似的查询集方法而引入的向后兼容的包装。这会影响以下类：`BaseModelAdmin`、`ChangeList`、`BaseCommentNode`、`GenericForeignKey`、`Manager`、`SingleRelatedObjectDescriptor` 和 `ReverseSingleRelatedObjectDescriptor`。

- 已经移除了为了重命名属性 `ChangeList.root_query_set` 和 `ChangeList.query_set` 而引入的向后兼容的包装。

- `django.views.defaults.shortcut` 和 `django.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.CacheMiddleware` 和 `django.middleware.cache.UpdateCacheMiddleware`，尽管在后者类中没有弃用警告。

- Usage of the hardcoded Hold down "Control", or "Command" on a Mac, to select more than one. string to override or append to user-provided `help_text` in forms for `ManyToMany` model fields is not performed by Django anymore either at the model or forms layer.

- `Model._meta.get_(add|change|delete)_permission` 方法已被移除。

- 不再读取会话键 `django_language` 以保持向后兼容性。

- 地理位置 Sitemaps 已被移除（`django.contrib.gis.sitemaps.views.index` 和 `django.contrib.gis.sitemaps.views.sitemap`）。

- `django.utils.html.fix_ampersands`、`fix_ampersands` 模板过滤器以及 `django.utils.html.clean_html` 都已被移除。