# Django 6.0.7 documentation

# 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` 表达式

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

### 次要特性

#### `django.contrib.admin`

- `ModelAdmin.date_hierarchy` 现在可以引用跨关联的字段。

- 新的 `ModelAdmin.get_exclude()` 钩子允许根据请求或模型实例指定要排除的字段。

- `popup_response.html` 模板现在可以按照每个应用程序、每个模型或通过设置 `ModelAdmin.popup_response_template` 属性来进行覆盖。

#### `django.contrib.auth`

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

- `LoginView` 和 `LogoutView` 基于类的视图替代了已弃用的 `login()` 和 `logout()` 基于函数的视图。

- `PasswordChangeView`、`PasswordChangeDoneView`、`PasswordResetView`、`PasswordResetDoneView`、`PasswordResetConfirmView` 和 `PasswordResetCompleteView` 基于类的视图替代了已弃用的 `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 失效。

- `LoginView` 和 `LogoutView` 的新属性 `success_url_allowed_hosts` 允许指定一组安全的主机，用于在登录和注销后进行重定向。

- 已添加密码验证器的 `help_text` 到 `UserCreationForm`。

- `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.com` 的 `OpenLayers.js`，这比旧的 `https://openlayers.org/` 源更适合生产使用。它们还更新为使用 OpenLayers 3。

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

- 现在可以在创建 `GDALRaster` 对象时传递 `size`、`shape` 和 `offset` 参数。

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

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

#### `django.contrib.postgres`

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

- 新的 `GinIndex` 和 `BrinIndex` 类允许在数据库中创建 `GIN` 和 `BRIN` 索引。

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

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

- 新的 `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()` 方法。

#### 表单

- 在 `CharField`、`EmailField`、`RegexField`、`SlugField` 和 `URLField` 上新增了 `empty_value` 属性，允许指定表示 "空" 的 Python 值。

- 新的 `Form.get_initial_for_field()` 方法返回表单字段的初始数据。

#### 国际化

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

#### 管理命令

- 新的 `loaddata --exclude` 选项允许在从 fixture 加载数据时排除模型和应用程序。

- 新的 `diffsettings --default` 选项允许指定与 Django 默认设置进行比较的设置模块。

- `app_label` 参数现在限制了 `showmigrations --plan` 输出。

#### 迁移

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

#### 模型

- 在 `QuerySet.update_or_create()` 和 `get_or_create()` 的 `defaults` 参数中新增了对可调用值的支持。

- `ImageField` now has a default `validate_image_file_extension` validator. (This validator moved to the form field in Django 1.11.2.)

- `Trunc` 函数现在支持时间截断。

- 新增了 `ExtractWeek` 函数，用于从 `DateField` 和 `DateTimeField` 中提取周，并通过 `week` 查询公开。

- 新增了 `TruncTime` 函数，用于将 `DateTimeField` 截断到其时间组件，并通过 `time` 查询公开。

- 在 `QuerySet.values()` 和 `values_list()` 中添加了对表达式的支持。

- 对于接受多个参数的查询，如 `range`，新增了对查询表达式的支持。

- 现在可以在 `FileField` 上使用 `unique=True` 选项。

- 新增了 `Expression.asc()` 和 `desc()` 的 `nulls_first` 和 `nulls_last` 参数，用于控制空值的排序顺序。

- 新的 `F` 表达式中的 `bitleftshift()` 和 `bitrightshift()` 方法允许进行 位移位操作。

- 新增了 `QuerySet.union()`、`intersection()` 和 `difference()` 方法。

#### 请求和响应

- 新增了 `QueryDict.fromkeys()` 方法。

- `CommonMiddleware` 现在为非流式响应设置 `Content-Length` 响应头。

- 新增了 `SECURE_HSTS_PRELOAD` 设置，允许将 `preload` 指令附加到 `Strict-Transport-Security` 头部。

- `ConditionalGetMiddleware` 现在将 `ETag` 头部添加到响应中。

#### 序列化

- 新的 `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` 指定特定的目录。

#### 测试

- 新增了 `DiscoverRunner.get_test_runner_kwargs()` 方法，允许自定义传递给测试运行器的关键字参数。

- 新增了 `test --debug-mode` 选项，通过将 `DEBUG` 设置为 `True` 来帮助排查测试失败。

- 新的 `django.test.utils.setup_databases()` （从 `django.test.runner` 移动过来）和 `teardown_databases()` 函数使构建自定义测试运行器更加容易。

- 在使用 `test --parallel` 选项时，新增了对 `unittest.TestCase.subTest()` 的支持。

- `DiscoverRunner` 现在在测试运行开始时运行系统检查。如果要禁用此功能，请覆盖 `DiscoverRunner.run_checks()` 方法。

#### 验证器

- 新增了 `FileExtensionValidator` 以验证文件扩展名，以及 `validate_image_file_extension` 以验证图像文件。

## 1.11 中的向后不兼容更改

### `django.contrib.gis`

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

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

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

- 基于 OpenLayers 的表单小部件现在使用 OpenLayers 3，同时更新了 `gis/openlayers.html` 和 `gis/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_type` 和 `field_name` 参数，并返回将给定时间字段 `field_name` 截断为只具有给定精度的时间对象的适当 SQL。`lookup_type` 参数可以是 `'hour'`、`'minute'` 或 `'second'`。

- 新增了 `DatabaseOperations.datetime_cast_time_sql()` 方法，以支持 `time` 查询。它接受一个 `field_name` 和 `tzname` 参数，并返回将日期时间值强制转换为时间值所需的 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.auth` 和 `i18n` 视图中加强了对不安全的重定向的保护。

`LoginView`、`LogoutView` （以及已弃用的函数式等效版本）和 `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 更改

`<p class="help">` 被替换为 `<div>` 标签，以允许在帮助文本中包含列表。

只读字段现在被包装在 `<div class="readonly">...</div>` 中，而不是 `<p>...</p>`，以允许字段内容包含任何类型的 HTML。

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

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

- `SubWidget`

- `RendererMixin`, `ChoiceFieldRenderer`, `RadioFieldRenderer`, `CheckboxFieldRenderer`

- `ChoiceInput`, `RadioChoiceInput`, `CheckboxChoiceInput`

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

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

如果 `settings.USE_L10N=True`，现在某些小部件的值，如 `<select>` 选项，将进行本地化。您可以通过使用 `localize` 模板标签关闭本地化，恢复到旧的行为，使用自定义小部件模板。

### `django.template.backends.django.Template.render()` 禁止非字典上下文。

为了与多个模板引擎兼容，`django.template.backends.django.Template.render()` （从高级模板加载器 API（如 `loader.get_template()`）返回）必须接收一个上下文字典，而不是 `Context` 或 `RequestContext`。如果您之前传递了这两个类中的任何一个，请改为传递一个字典 - 这样做是向后兼容旧版本的 Django。

### 迁移操作中的模型状态更改

为了提高应用迁移的速度，延迟了相关模型的渲染，直到需要它们的操作（例如 `RunPython`）。如果您有一个自定义操作，需要在 `database_forwards()` 或 `database_backwards()` 的 `from_state` 参数中使用模型类或模型实例，您必须使用 `clear_delayed_apps_cache()` 方法来渲染模型状态，如 编写自己的迁移操作 中所述。

### PostgreSQL 上的服务器端游标

The change to make `QuerySet.iterator()` use server-side cursors on PostgreSQL prevents running Django with PgBouncer in transaction pooling mode. To reallow that, use the `DISABLE_SERVER_SIDE_CURSORS` setting (added in Django 1.11.1) in `DATABASES`.

有关更多讨论，请参阅 事务池和服务器端游标。

### 杂项

- 如果在 feed 中没有任何项目具有 `pubdate` 或 `updateddate` 属性，那么 `SyndicationFeed.latest_post_date()` 现在会返回当前的 UTC 日期/时间，而不是一个没有任何时区信息的 datetime。

- CSRF 失败现在会被记录到 `django.security.csrf` 日志器，而不是 `django.request`。

- 运行测试时，不再禁用 `ALLOWED_HOSTS` 验证。如果您的应用程序包括具有自定义主机名的测试，您必须将这些主机名包含在 `ALLOWED_HOSTS` 中。请参阅 测试与多主机名。

- 在 `ModelAdmin.list_display` 中使用外键的 id（例如 `'field_id'`）会显示相关对象的 ID。如果要恢复到对象的字符串表示的旧行为，请移除 `_id` 后缀。

- 在模型表单中，具有 `null=True` 的 `CharField` 现在会为空白值保存 `NULL`，而不是空字符串。

- 在 Oracle 上，`Model.validate_unique()` 不再检查空字符串的唯一性，因为数据库会将该值解释为 `NULL`。

- 如果您子类化了 `AbstractUser` 并覆盖了 `clean()` 方法，请确保它调用了 `super()`。新的 `AbstractUser.clean()` 方法中会调用 `BaseUserManager.normalize_email()`，以便在模型表单验证等情况下应用标准化。

- `EmailField` 和 `URLField` 不再接受 `strip` 关键字参数。移除它，因为在旧版本的 Django 中它没有任何效果，这些字段总是会去除空格。

- 表单小部件渲染的 `checked` 和 `selected` 属性现在使用 HTML5 布尔语法，而不再使用 XHTML 的 `checked='checked'` 和 `selected='selected'`。

- `RelatedManager.add()`、`remove()`、`clear()` 和 `set()` 现在会清除 `prefetch_related()` 缓存。

- 为防止可能丢失的保存设置，如果在调用 `teardown_test_environment()` 之前再次调用 `setup_test_environment()`，它现在会引发异常。

- 未记录的 `DateTimeAwareJSONEncoder` 别名（对于在 Django 1.0 中更名的 `DjangoJSONEncoder`）已被移除。

- 如果没有指定 `OPTIONS['loaders']` 并且 `OPTIONS['debug']` 为 `False` （后者默认为 `DEBUG` 的值），则现在会启用 `cached template loader`。如果您有一些不是线程安全的 模板标签，这可能会导致不兼容。

- 过去在运行 `migrate` 命令之后不再提示删除陈旧的内容类型。现在请使用新的 `remove_stale_contenttypes` 命令。

- 管理员界面中的 `IntegerField` 控件现在使用 `type="number"` 而不是 `type="text"`。

- 现在，条件 HTTP 标头根据 RFC 7232 的条件请求规范进行解析和比较，而不是较旧的 RFC 2616 规范。

- `patch_response_headers()` 不再添加 `Last-Modified` 标头。根据 RFC 7234 Section 4.2.2，在提供明确的过期时间的其他缓存标头旁边，例如 `Expires` 或 `Cache-Control`，此标头是无用的。因此，`UpdateCacheMiddleware` 和 `add_never_cache_headers()` 调用 `patch_response_headers()`，因此也受到此更改的影响。

- 在管理模板中，`<p class="help">` 被替换为 `<div>` 标签，以允许在帮助文本中包含列表。

- `ConditionalGetMiddleware` 不再设置 `Date` 头，因为 web 服务器会设置该头。它也不再设置 `Content-Length` 头，因为现在由 `CommonMiddleware` 完成此操作。

  如果您有一个中间件在 `MIDDLEWARE` 或 `MIDDLEWARE_CLASSES` 设置中出现在 `CommonMiddleware` 之前，并且修改响应的内容，那么您必须重新排列您的中间件，以确保在设置 `Content-Length` 后不会修改响应，或者让修改响应的中间件重置 `Content-Length` 头。

- `get_model()` 和 `get_models()` 现在在所有应用程序的模型加载之前调用时会引发 `AppRegistryNotReady` 异常。以前它们只需要目标应用程序的模型被加载，因此可能返回未完全设置其关系的模型。如果您需要 `get_model()` 的旧行为，请将 `require_ready` 参数设置为 `False`。

- 未使用的 `BaseCommand.can_import_settings` 属性已被删除。

- 未记录的 `django.utils.functional.lazy_property` 已被移除。

- 为了与非多部分请求保持一致，`MultiPartParser.parse()` 现在会使 `request.POST` 保持不可变性。如果你要修改那个 `QueryDict`，你现在必须先复制它，例如 `request.POST.copy()`。

- 对于 `cx_Oracle` 版本小于 5.2 的支持已被移除。

- 对于 IPython 版本小于 1.0 的支持已从 `shell` 命令中移除。

- 私有 API `Widget.build_attrs()` 的签名已从 `extra_attrs=None, **kwargs` 更改为 `base_attrs, extra_attrs=None`。

- 通过测试客户端上传到一个 `ImageField` 的类似文件的对象（例如 `StringIO` 和 `BytesIO`）现在需要一个具有通过 `validate_image_file_extension` 验证器的值的 `name` 属性。请参阅 `Client.post()` 中的注意事项。

- `FileField` 现在会移动文件而不是复制它所接收的文件。使用默认的文件上传设置，文件大小超过 `FILE_UPLOAD_MAX_MEMORY_SIZE` 的文件现在具有与临时文件相同的权限（通常是 `0o600`），而不是系统的标准掩码（通常是 `0o644`）。如果您需要不考虑文件大小都具有相同权限，请设置 `FILE_UPLOAD_PERMISSIONS`。

## 在 1.11 中被废弃的功能

### `models.permalink()` 装饰器

请使用 `django.urls.reverse()`。例如：

    from django.db import models

    class MyModel(models.Model):
        ...

        @models.permalink
        def url(self):
            return ("guitarist_detail", [self.slug])

变成：

    from django.db import models
    from django.urls import reverse

    class MyModel(models.Model):
        ...

        def url(self):
            return reverse("guitarist_detail", args=[self.slug])

### 杂项

- `contrib.auth` 中的 `login()` 和 `logout()` 基于函数的视图已被弃用，推荐使用新的基于类的视图 `LoginView` 和 `LogoutView`。

- `contrib.auth.views.logout_then_login()` 的未使用的 `extra_context` 参数已被弃用。

- `contrib.auth` 中的 `password_change()`, `password_change_done()`, `password_reset()`, `password_reset_done()`, `password_reset_confirm()`, 和 `password_reset_complete()` 基于函数的视图已被弃用，推荐使用新的基于类的视图 `PasswordChangeView`, `PasswordChangeDoneView`, `PasswordResetView`, `PasswordResetDoneView`, `PasswordResetConfirmView`, 和 `PasswordResetCompleteView`。

- `django.test.runner.setup_databases()` 已移至 `django.test.utils.setup_databases()`。旧位置已被弃用。

- `django.utils.translation.string_concat()` 已被弃用，推荐使用 `django.utils.text.format_lazy()`。可以通过 `format_lazy('{}' * len(strings), *strings)` 来替代 `string_concat(*strings)`。

- 对于 `PyLibMCCache` 缓存后端，将 `pylibmc` 行为设置作为 `OPTIONS` 的顶级属性传递已被弃用。请将它们设置在 `OPTIONS` 内的 `behaviors` 键下。

- `django.utils.http.is_safe_url()` 的 `host` 参数已被弃用，推荐使用新的 `allowed_hosts` 参数。

- 在渲染 `{% include %}` 模板标签时抑制异常已被弃用，因为这种行为通常会比有帮助更令人困惑。在 Django 2.1 中，将会引发异常。

- `DatabaseIntrospection.get_indexes()` 已被弃用，推荐使用 `DatabaseIntrospection.get_constraints()`。

- `authenticate()` 现在向身份验证后端的 `authenticate()` 方法传递一个 `request` 参数。不接受 `request` 作为第一个位置参数的方法将在 Django 2.1 中被移除。

- `USE_ETAGS` 设置已被弃用，推荐使用 `ConditionalGetMiddleware`，它现在会在响应中添加 `ETag` 头，不受设置的影响。当弃用结束时，`CommonMiddleware` 和 `django.utils.cache.patch_response_headers()` 将不再设置 ETags。

- `Model._meta.has_auto_field` 已被弃用，推荐检查 `Model._meta.auto_field is not None`。

- 在 `url()` 中使用带有 `iLmsu#` 的正则表达式组已被弃用。唯一有用的组是 `(?i)` 用于不区分大小写的 URL，但是不区分大小写的 URL 并不是一个好的实践，因为它们会为搜索引擎创建多个条目，例如。一个替代方案可能是创建一个 `handler404`，它查找 URL 中的大写字符并重定向到相应的小写字符。

- `renderer` 参数已添加到 `Widget.render()` 方法。不接受该参数的方法将在一个弃用期内继续工作。