# Django 6.0.7 documentation

# Django 1.7 版本发行说明

2014 年 9 月 2 日

欢迎使用 Django 1.7 ！

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

## Python 兼容性

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

Django 1.6 系列是最后一个支持 Python 2.6 的版本。 Django 1.7 是第一个支持 Python 3.4 的版本。

这个改变应该只影响少数 Django 用户，因为大多数操作系统供应商现在都将 Python 2.7 或更新版本作为默认版本发布。然而，如果您仍在使用 Python 2.6，那么您需要继续使用 Django 1.6，直到您可以升级您的 Python 版本。根据 我们的支持政策，Django 1.6 将继续获得安全支持，直到 Django 1.8 发布为止。

## Django 1.7 的新特性包括：

### 模式迁移

Django 现在内置了对模式迁移的支持。它允许通过创建迁移文件来更新、修改和删除模型，这些迁移文件代表了模型的变更，可以在任何开发、暂存或生产数据库上运行。

迁移在 自己的文档中 中有详细的介绍，但其中一些关键特性包括：

- `syncdb` 已经被弃用，被 `migrate` 取代。不用担心 - 对 `syncdb` 的调用仍然会像以前一样工作。

- 新的 `makemigrations` 命令提供了一种自动检测模型更改并为其创建迁移的简便方法。

  `django.db.models.signals.pre_syncdb` 和 `django.db.models.signals.post_syncdb` 已经被弃用，分别由 `pre_migrate` 和 `post_migrate` 取代。这些新信号具有稍微不同的参数。请查阅文档以获取详细信息。

- 数据库路由器上的 `allow_syncdb` 方法现在被称为 `allow_migrate`，但仍然执行相同的功能。具有 `allow_syncdb` 方法的路由器仍然可以工作，但该方法名称已被弃用，您应尽快更改它（只需要重命名即可）。

- 不再为具有迁移的应用程序加载 `initial_data` fixture；如果您想为应用程序加载初始数据，建议您为应用程序创建一个迁移，并在迁移的 `operations` 部分中定义一个 `RunPython` 或 `RunSQL` 操作。

- 对于具有迁移的应用程序，测试回滚行为会有所不同；特别是，Django 不再在非事务性数据库上或 `TransactionTestCase` 内模拟回滚，除非明确请求（除非明确请求）。

- 不建议没有迁移的应用程序依赖于（具有 `ForeignKey` 或 `ManyToManyField` 的）具有迁移的应用程序。

### 应用加载重构

在过去，Django 应用与模型紧密耦合。一个名为 "应用缓存" 的单例处理已安装的应用和模型。许多 API 中使用模型模块作为应用的标识符。

随着 Django 应用程序 概念的成熟，这段代码显示出了一些不足之处。它已经被重构为一个 "应用程序注册表"，在这里模型模块不再起到核心作用，同时可以将配置数据附加到应用程序。

迄今为止的改进包括：

- 应用程序可以在启动时运行代码，在 Django 执行任何其他操作之前，使用其配置的 `ready()` 方法。

- 即使在 `models.py` 之外定义模型，应用程序标签也会被正确地分配给模型。您不再需要显式设置 `app_label`。

- 如果一个应用程序没有任何模型，完全可以省略 `models.py`。

- 可以使用应用程序配置的 `label` 属性重新标记应用程序，以解决标签冲突。

- 可以使用应用程序配置的 `verbose_name` 来自定义在管理员界面中的应用程序名称。

- The admin automatically calls `autodiscover()` when Django starts. You can consequently remove this line from your URLconf.

- Django 在启动时通过一种确定性且简单的过程导入所有应用程序配置和模型。这将使诊断导入问题（如导入循环）变得更容易。

### Field 子类的新方法

为了支持模式迁移并使未来版本的 Django 更容易添加复合键，`Field` API 现在有一个新的必需方法：`deconstruct()`。

该方法不接受任何参数，并返回一个包含四个元素的元组：

- `name`：字段在其父模型上的属性名称，如果它不是模型的一部分，则为 `None`。

- `path`：字段类的点分隔的 Python 路径，包括类名。

- `args`：作为列表的位置参数。

- `kwargs`：作为字典的关键字参数。

这四个值允许将任何字段序列化到文件中，并且允许字段进行安全复制，这是这些新功能的重要组成部分。

这个变化不会影响您，除非您编写自定义的 Field 子类；如果您这样做，如果您的子类以任何方式更改了 `__init__` 的方法签名，您可能需要重新实现 `deconstruct()` 方法。如果您的字段只是继承自内置的 Django 字段，并且没有重写 `__init__`，则无需进行任何更改。

如果您确实需要重写 `deconstruct()`，一个好的起点是内置的 Django 字段（`django/db/models/fields/__init__.py`），因为其中一些字段，包括 `DecimalField` 和 `DateField`，已经重写了它，并展示了如何在超类上调用该方法，只需添加或删除额外的参数。

这也意味着字段的所有参数本身必须是可序列化的；要了解我们认为什么是可序列化的，以及如何使您自己的类可序列化，请阅读 迁移序列化文档。

### 从 `Manager` 中调用自定义的 `QuerySet` 方法

历史上，制作可重用的模型查询的推荐方法是在自定义 `Manager` 类上创建方法。这种方法的问题在于，在第一次方法调用之后，您会得到一个 `QuerySet` 实例，无法调用其他自定义的管理器方法。

尽管没有记录，但通常可以通过创建自定义的 `QuerySet` 来解决这个问题，以便可以链接自定义方法；但是这个解决方案有很多缺点：

- 自定义的 `QuerySet` 和其自定义方法在第一次调用 `values()` 或 `values_list()` 后就丢失了。

- 仍然需要编写自定义的 `Manager` 来返回自定义的 `QuerySet` 类，并且所有希望在 `Manager` 上使用的方法都必须被代理到 `QuerySet` 上。整个过程违反了 DRY 原则。

现在可以直接使用 `QuerySet.as_manager()` 类方法来 创建具有 QuerySet 方法的 Manager：

    class FoodQuerySet(models.QuerySet):
        def pizzas(self):
            return self.filter(kind="pizza")

        def vegetarian(self):
            return self.filter(vegetarian=True)

    class Food(models.Model):
        kind = models.CharField(max_length=50)
        vegetarian = models.BooleanField(default=False)
        objects = FoodQuerySet.as_manager()

    Food.objects.pizzas().vegetarian()

### 在遍历反向关系时使用自定义管理器

现在可以在遍历反向关系时 指定自定义的管理器：

    class Blog(models.Model):
        pass

    class Entry(models.Model):
        blog = models.ForeignKey(Blog)

        objects = models.Manager()  # Default Manager
        entries = EntryManager()  # Custom Manager

    b = Blog.objects.get(id=1)
    b.entry_set(manager="entries").all()

### 新的系统检查框架

我们新增了一个新的 系统检查框架，用于检测常见问题（比如无效的模型）并提供解决这些问题的提示。这个框架是可扩展的，因此您可以为自己的应用程序和库添加自定义检查。

要执行系统检查，您可以使用 `check` 管理命令。这个命令替代了旧的 `validate` 管理命令。

### 新的 `Prefetch` 对象用于高级的 `prefetch_related` 操作。

新的 `Prefetch` 对象允许自定义预取操作。

您可以指定用于遍历特定关系的 `QuerySet`，或者自定义预取结果的存储位置。

This enables things like filtering prefetched relations, calling `select_related()` from a prefetched relation, or prefetching the same relation multiple times with different querysets. See `prefetch_related()` for more details.

### 管理快捷方式支持时区

在管理员中日期和时间输入小部件旁边的 "today" 和 "now" 快捷方式现在在 当前时区 中运行。以前，它们使用浏览器的时区，这可能导致在时区不匹配服务器的当前时区时保存错误的值。

此外，小部件现在在浏览器和服务器时区不同时显示帮助信息，以明确解释字段中插入的值将如何被解释。

### 使用数据库游标作为上下文管理器

在 Python 2.7 之前，数据库游标可以用作上下文管理器。具体的后端游标定义了上下文管理器的行为。但是，Python 2.7 改变了魔术方法查找的行为，游标不再能用作上下文管理器。

Django 1.7 允许将游标用作上下文管理器。也就是说，可以使用以下方式：

    with connection.cursor() as c:
        c.execute(...)

替换成：

    c = connection.cursor()
    try:
        c.execute(...)
    finally:
        c.close()

### 自定义查找

现在可以为 ORM 编写自定义查找和转换。自定义查找与 Django 内置的查找（例如 `lte`、`icontains`）类似，而转换是一个新概念。

`django.db.models.Lookup` 类提供了一种为模型字段添加查找运算符的方式。例如，可以为 `DateFields` 添加 `day_lte` 运算符。

`django.db.models.Transform` 类允许在最终查找之前对数据库值进行转换。例如，可以编写一个 `year` 转换，从字段的值中提取年份。转换允许进行链式操作。在将 `year` 转换添加到 `DateField` 后，可以对转换后的值进行筛选，例如 `qs.filter(author__birthdate__year__lte=1981)`。

有关自定义查找和转换的更多信息，请参阅 自定义查找 文档。

### 改进了 `Form` 错误处理

#### `Form.add_error()`

以前在处理表单错误方面有两种主要模式：

- 在某些函数（例如 `Field.clean()`、`Form.clean_<fieldname>()` 或 `Form.clean()` 用于非字段错误的情况）中引发 `ValidationError`。

- 在 `Form.clean()` 中针对特定字段或在“clean”方法之外（例如直接从视图中）添加错误时，会涉及到 `Form._errors`。

使用前一种模式是直接的，因为表单可以根据上下文（即引发异常的方法）猜测错误的归属，并自动处理它们。这仍然是可能时添加错误的规范方式。然而，后一种模式很繁琐且容易出错，因为处理边缘情况的负担落在用户身上。

The new `add_error()` method allows adding errors to specific form fields from anywhere without having to worry about the details such as creating instances of `django.forms.utils.ErrorList` or dealing with `Form.cleaned_data`. This new API replaces manipulating `Form._errors` which now becomes a private API.

请参阅 使用 Form.add_error() 进行字段验证，以获取使用 `Form.add_error()` 的示例。

#### 错误元数据

`ValidationError` 构造函数接受元数据，如错误 `code` 或 `params`，然后可以将其插入到错误消息中（有关更多详细信息，请参阅 引发 ValidationError）；然而，在 Django 1.7 之前，这些元数据在错误添加到 `Form.errors` 后立即被丢弃。

`Form.errors` 和 `django.forms.utils.ErrorList` 现在存储了 `ValidationError` 实例，因此可以通过新的 `Form.errors.as_data` 方法在任何时候检索这些元数据。

检索到的 `ValidationError` 实例可以通过其错误 `code` 进行标识，从而可以进行诸如重写错误消息或在特定错误存在时编写视图中的自定义逻辑等操作。它还可以用于以自定义格式（例如 XML）序列化错误。

新的 `Form.errors.as_json()` 方法是一个方便的方法，它返回以 JSON 格式序列化的错误消息以及错误代码。`as_json()` 使用了 `as_data()`，并展示了如何扩展新系统的思路。

#### 错误容器和向后兼容性

为了支持上述功能，需要对各种错误容器进行重大更改，特别是 `Form.errors`、`django.forms.utils.ErrorList` 和 `ValidationError` 的内部存储。这些容器曾经存储错误字符串，现在存储 `ValidationError` 实例，并且公共 API 已经进行了适应，使这些更改尽可能透明，但如果您曾经使用过私有 API，一些更改可能不兼容向后；有关更多详细信息，请参阅 ValidationError 构造函数和内部存储。

### 次要特性

#### `django.contrib.admin`

- 现在可以在自定义的 `AdminSite` 上实现 `site_header`、`site_title` 和 `index_title` 属性，以便轻松更改管理站点的页面标题和页眉文本。不再需要覆盖模板！

- 在 `django.contrib.admin` 中的按钮现在使用 `border-radius` CSS 属性来实现圆角，而不再使用 GIF 背景图像。

- 一些管理模板现在在其 `<body>` 标签中具有 `app-<app_name>` 和 `model-<model_name>` 类，以允许按应用程序或模型自定义 CSS 样式。

- 管理员变更列表单元格现在在 HTML 中具有 `field-<field_name>` 类，以启用样式自定义。

- 现在可以通过新的 `django.contrib.admin.ModelAdmin.get_search_fields()` 方法，按请求自定义管理员的搜索字段。

- 可以重写 `ModelAdmin.get_fields()` 方法来自定义 `ModelAdmin.fields` 的值。

- 除了现有的 `admin.site.register` 语法之外，您还可以使用新的 `register()` 装饰器来注册一个 `ModelAdmin`。

- 您可以指定 `ModelAdmin.list_display_links` `= None` 来禁用更改列表页面网格上的链接。

- 现在可以指定 `ModelAdmin.view_on_site` 来控制是否显示 "在站点上查看" 链接。

- 您可以通过在 `admin_order_field` 值前面加上连字符来指定 `ModelAdmin.list_display` 值的降序排序。

- 可以重写 `ModelAdmin.get_changeform_initial_data()` 方法来定义设置更改表单初始数据的自定义行为。

#### `django.contrib.auth`

- Any `**kwargs` passed to `email_user()` are passed to the underlying `send_mail()` call.

- `permission_required()` 装饰器可以接受一组权限，而不仅仅是单个权限。

- 您可以重写新的 `AuthenticationForm.confirm_login_allowed()` 方法，以更轻松地自定义登录策略。

- `django.contrib.auth.views.password_reset()` 接受一个可选的 `html_email_template_name` 参数，用于发送包含 HTML 的多部分电子邮件以进行密码重置。

- 添加了 `AbstractBaseUser.get_session_auth_hash()` 方法，如果您的 `AUTH_USER_MODEL` 继承自 `AbstractBaseUser`，那么现在在启用了 `django.contrib.auth.middleware.SessionAuthenticationMiddleware` 的情况下，更改用户密码会使旧的会话失效。有关更多详细信息，请参阅 密码更改时的会话失效。

#### `django.contrib.formtools`

- 对 `WizardView.done()` 的调用现在包括一个 `form_dict`，以便更容易按步骤名称访问表单。

#### `django.contrib.gis`

- 默认包含在小部件中的 OpenLayers 库版本已从 2.11 更新为 2.13 。

- 如果安装了 GEOS 3.3 或更高版本，预处理的几何图形现在还支持 `crosses`、`disjoint`、`overlaps`、`touches` 和 `within` 谓词。

#### `django.contrib.messages`

- 使用 Cookie 的 `django.contrib.messages` 后端现在将遵循 `SESSION_COOKIE_SECURE` 和 `SESSION_COOKIE_HTTPONLY` 设置。

- 消息上下文处理器 现在会添加一个名为 `DEFAULT_MESSAGE_LEVELS` 的默认级别字典。

- 现在 `Message` 对象具有一个 `level_tag` 属性，其中包含消息级别的字符串表示。

#### `django.contrib.redirects`

- `RedirectFallbackMiddleware` 具有两个新属性 (`response_gone_class` 和 `response_redirect_class`)，用于指定中间件返回的 `HttpResponse` 实例的类型。

#### `django.contrib.sessions`

- `"django.contrib.sessions.backends.cached_db"` 会话后端现在尊重 `SESSION_CACHE_ALIAS`。在之前的版本中，它总是使用 `default` 缓存。

#### `django.contrib.sitemaps`

- `sitemap framework` 现在使用 `lastmod` 来设置响应中的 `Last-Modified` 标头。这使得 `ConditionalGetMiddleware` 可以处理对设置了 `lastmod` 的站点地图的条件 `GET` 请求。

#### `django.contrib.sites`

- 新的 `django.contrib.sites.middleware.CurrentSiteMiddleware` 允许在每个请求上设置当前站点。

#### `django.contrib.staticfiles`

- 可以通过子类化 静态文件存储类 来覆盖收集的静态文件和目录的权限，方法是设置 `file_permissions_mode` 和 `directory_permissions_mode` 参数。请参阅 `collectstatic` 以查看示例用法。

- `CachedStaticFilesStorage` 后端有一个名为 `ManifestStaticFilesStorage` 的兄弟类，它根本不使用缓存系统，而是使用一个名为 `staticfiles.json` 的 JSON 文件来存储原始文件名（例如 `css/styles.css`）和散列文件名（例如 `css/styles.55e7cbb9ba48.css`）之间的映射关系。当运行 `collectstatic` 管理命令时，会创建 `staticfiles.json` 文件，对于 Amazon S3 等远程存储来说，这应该是一个更经济的替代方案。

  有关更多信息，请参阅 `ManifestStaticFilesStorage` 文档。

- `findstatic` 现在接受详细程度为 2 的 verbosity 标志，这意味着它将显示搜索的目录的相对路径。请参阅 `findstatic` 以查看示例输出。

#### `django.contrib.syndication`

- `Atom1Feed` 辅助工具中的 `updated` 元素现在使用 `updateddate` 而不是 `pubdate`，允许在 feed 中包含 `published` 元素（该元素依赖于 `pubdate`）。

#### 缓存

- 现在可以通过 `django.core.cache.caches` 访问在 `CACHES` 中配置的缓存。这个类似字典的对象为每个线程提供一个不同的实例。它取代了已被弃用的 `django.core.cache.get_cache()`。

- 如果直接实例化缓存后端，请注意它们不再是线程安全的，因为 `django.core.cache.caches` 现在为每个线程提供不同的实例。

- 将 `CACHES` 设置的 `TIMEOUT` 参数定义为 `None` 将默认将缓存键设置为 "永不过期"。以前，只能将 `timeout=None` 传递给缓存后端的 `set()` 方法。

#### 跨站请求伪造（Cross Site Request Forgery，CSRF）

- `CSRF_COOKIE_AGE` 设置方便了使用基于会话的 CSRF Cookie。

#### 电子邮件

- `send_mail()` 现在接受一个 `html_message` 参数，用于发送多部分 text/plain 和 text/html 的电子邮件。

- The SMTP EmailBackend now accepts a `timeout` parameter.

#### 文件存储

- 在 Windows 上，文件锁定以前依赖于 PyWin32 软件包；如果未安装该软件包，则文件锁定会默默失败。现在已经移除了这个依赖项，文件锁定在 Windows 和 Unix 上都使用本地实现。

#### 文件上传

- 新的 `UploadedFile.content_type_extra` 属性包含在文件上传的 `content-type` 标头中传递的额外参数。

- 新的 `FILE_UPLOAD_DIRECTORY_PERMISSIONS` 设置控制在文件上传期间创建的目录的文件系统权限，就像 `FILE_UPLOAD_PERMISSIONS` 一样控制文件本身的权限。

- `FileField.upload_to` 属性现在是可选的。如果省略或给定 `None` 或空字符串，将不会使用子目录来存储上传的文件。

- 上传的文件现在在响应交付给客户端之前明确关闭。只要在上传处理程序中的名称为 `file`，部分上传的文件也会被关闭。

- `Storage.get_available_name()` 现在追加一个下划线加上一个随机的 7 个字符的字母数字字符串（例如，`"_x3a1gho"`），而不是通过一个下划线后跟一个数字（例如，`"_1"`, `"_2"` 等）来进行迭代，以防止拒绝服务攻击。这个更改也在 1.6.6、1.5.9 和 1.4.14 安全发布版中进行了更改。

#### 表单

- `RadioSelect` 和 `CheckboxSelectMultiple` 渲染的单选按钮或复选框的 `<label>` 和 `<input>` 标签现在分别包括 `for` 和 `id` 属性。每个单选按钮或复选框都包括一个 `id_for_label` 属性以输出元素的 ID。

- `Textarea` 渲染的 `<textarea>` 标签现在如果 `TextField` 模型字段有 `max_length`，则会包括一个 `maxlength` 属性。

- `Field.choices` 现在允许您通过包含一个空字符串或 `None` 的元组作为键以及自定义标签作为值来自定义 "空选项" 标签。在这种情况下，默认的空选项 `"----------"` 将被省略。

- `MultiValueField` 允许通过将 `require_all_fields` 参数设置为 `False` 来添加可选子字段。将尊重每个单独字段的 `required` 属性，并且当任何必填字段为空时，将引发新的 `incomplete` 验证错误。

- 表单上的 `clean()` 方法不再需要返回 `self.cleaned_data`。如果它返回一个已更改的字典，那么仍将使用该字典。

- 在 Django 1.6 中的一个临时回归之后，现在可以再次使 `TypedChoiceField` 的 `coerce` 方法返回任意值。

- `SelectDateWidget.months` 可以用于自定义在选择小部件中显示的月份的措辞。

- 添加了 `min_num` 和 `validate_min` 参数到 `formset_factory()`，以允许验证提交的表单的最小数量。

- `Form` 和 `ModelForm` 使用的元类已经重新设计，以支持更多的继承情况。以前的限制，阻止同时继承 `Form` 和 `ModelForm` 已经被移除，只要 `ModelForm` 在方法解析顺序 (MRO) 中首先出现。

- 现在可以通过将字段的名称设置为 `None` 来在子类中从 `Form` 中删除字段。

- 现在可以自定义 `ModelForm` 中的 `unique`、`unique_for_date` 和 `unique_together` 约束的错误消息。为了支持 `unique_together` 或任何其他 `NON_FIELD_ERROR`，`ModelForm` 现在会查找 `ModelForm` 内部 `Meta` 类的 `error_messages` 字典中的 `NON_FIELD_ERROR` 键。有关更多详细信息，请参阅 关于模型的 error_messages 的考虑。

#### 国际化

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

- `LocaleMiddleware` 现在将用户选择的语言存储在会话键 `_language` 中。这应该只使用 `LANGUAGE_SESSION_KEY` 常量来访问。以前它存储在键 `django_language` 中，而 `LANGUAGE_SESSION_KEY` 常量不存在，但为 Django 保留的键应该以下划线开头。为了向后兼容，在 1.7 中仍然从 `django_language` 读取。随着写入，会话将迁移到新的键。

- `blocktrans` 标签现在支持一个 `trimmed` 选项。此选项将从 `{% blocktrans %}` 标签的内容的开头和结尾删除换行符，替换每行开头和结尾的任何空白，并使用空格字符将所有行合并为一行，以分隔它们。这对于缩进 `{% blocktrans %}` 标签的内容非常有用，而不会使缩进字符出现在 `.po` 文件中相应的条目中，从而使翻译过程更加容易。

- 当你在项目的根目录运行 `makemessages` 时，任何提取出来的字符串现在将自动分发到正确的应用程序或项目消息文件中。详细信息请参见 本地化：如何创建语言文件。

- `makemessages` 命令现在总是会将 `--previous` 命令行标志添加到 `msgmerge` 命令中，以保留先前翻译的模糊字符串在 `.po` 文件中。

- 引入了以下用于调整语言 cookie 选项的设置：`LANGUAGE_COOKIE_AGE`、`LANGUAGE_COOKIE_DOMAIN` 和 `LANGUAGE_COOKIE_PATH`。

- 添加了用于 Esperanto 的 本地格式化。

#### 管理命令

- 新的 `--no-color` 选项用于 `django-admin`，用于禁用管理命令输出的颜色标记。

- 新的 `dumpdata --natural-foreign` 和 `dumpdata --natural-primary` 选项，以及 `serializers.serialize()` 的新参数 `use_natural_foreign_keys` 和 `use_natural_primary_keys` 允许在序列化时使用自然主键。

- 不再需要为 `createcachetable` 命令提供缓存表名或 `--database` 选项。Django 会从你的设置文件中获取这些信息。如果你配置了多个缓存或多个数据库，所有缓存表都会被创建。

- `runserver` 命令进行了一些改进：

  - 在 Linux 系统上，如果安装了 pyinotify，开发服务器将在文件更改时立即重新加载。以前，它每秒轮询文件系统以检测更改，这会导致重新加载前有一小段延迟，并降低笔记本电脑的电池寿命。

  - 此外，当翻译文件更新后，即在运行 `compilemessages` 后，开发服务器会自动重新加载。

  - 所有 HTTP 请求都会记录到控制台，包括以前被过滤掉的用于静态文件或 `favicon.ico` 的请求。

- 如果安装并激活了第三方工具 ANSICON，Windows 下的管理命令现在可以生成带有语法着色的输出。

- `collectstatic` 命令现在在 Windows NT 6 (Windows Vista 及更新版本) 上支持符号链接选项。

- 如果安装了 sqlparse Python 库，初始 SQL 数据现在将更好地工作。

  请注意，它已被弃用，推荐使用迁移的 `RunSQL` 操作，这样可以受益于改进后的行为。

#### 模型

- 新增了 `QuerySet.update_or_create()` 方法。

- 新的 `default_permissions` 模型 `Meta` 选项允许你自定义（或禁用）默认添加、修改和删除权限的创建。

- 现在在抽象类中可以显式使用 `OneToOneField` 用于 多表继承。

- 现在可以通过将 `OneToOneField` 的 `related_name` 设置为 `'+'` 或以 `'+'` 结尾来避免创建反向关系。

- `F 表达式` 支持幂运算符（`**`）。

- 由 `ForeignKey` 和 `GenericForeignKey` 创建的关联管理器的 `remove()` 和 `clear()` 方法现在接受 `bulk` 关键字参数，用于控制是否批量执行操作（即使用 `QuerySet.update()`）。默认为 `True`。

- 现在可以将 `None` 用作 `iexact` 查找的查询值。

- 现在在定义 `ForeignKey` 或 `ManyToManyField` 时，可以将可调用对象作为属性 `limit_choices_to` 的值传递。

- 在 `QuerySet.values()` 的结果上调用 `only()` 和 `defer()` 现在会引发错误（之前会导致数据库错误或不正确的数据）。

- 在指定单个字段集时，可以使用单个列表（而不是列表的列表）作为 `index_together` 的值。

- 现在允许自定义中间模型具有多个外键与参与多对多关系的任何模型相关联，前提是你通过设置新的 `ManyToManyField.through_fields` 参数来明确指定应该使用哪些外键。

- 现在，将模型实例分配给非关联字段将会抛出错误。之前，如果字段接受整数作为输入并将其作为主键，这样的操作是有效的。

- 整数字段现在会根据它们的 `internal_type` 验证数据库后端特定的最小值和最大值。以前，模型字段的验证不会阻止保存超出其关联列数据类型范围的值，从而导致完整性错误。

- 现在可以通过使用关联字段的属性名称来显式 `order_by()` 一个关系的 `_id` 字段。

#### 信号

- 在 `setting_changed` 信号中添加了 `enter` 参数。

- 现在可以使用 `'app_label.ModelName'` 形式的 `str` 来连接模型信号，就像相关字段一样，以惰性引用它们的发送者。

#### 模板

- `Context.push()` 方法现在返回一个上下文管理器，在退出 `with` 语句时会自动调用 `pop()`。此外，`push()` 现在接受参数，这些参数将传递给用于构建新上下文级别的 `dict` 构造函数。

- 新的 `Context.flatten()` 方法将一个 `Context` 的堆栈返回为一个扁平的字典。

- `Context` 对象现在可以进行相等性比较（内部使用 `Context.flatten()` 进行比较，因此只要它们的扁平化版本相同，每个 `Context` 的堆栈的内部结构就不重要）。

- `widthratio` 模板标签现在接受一个 `"as"` 参数，以将结果存储在一个变量中。

- `include` 模板标签现在还接受任何具有 `render()` 方法的对象（例如 `Template`）作为参数。字符串参数将如常使用 `get_template()` 进行查找。

- 现在可以递归地使用 `include` 模板。

- 当 `TEMPLATE_DEBUG` 为 `True` 时，模板对象现在具有一个设置的 origin 属性。这允许在 `django.template` 基础结构之外检查和记录模板的来源。

- 在模板渲染过程中引发的 `TypeError` 异常不再被消除声音。

- 以下函数现在接受一个 `dirs` 参数，这是一个列表或元组，用于覆盖 `TEMPLATE_DIRS`：

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

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

  - `django.shortcuts.render()`

  - `django.shortcuts.render_to_response()`

- `time` 过滤器现在接受与时区相关的 格式说明符 `'e'`, `'O'`, `'T'` 和 `'Z'`，并且能够处理 时区感知的 `datetime` 实例，执行预期的渲染。

- `cache` 标签现在会尝试使用名为 "template_fragments" 的缓存（如果存在），否则会回退使用默认缓存。它还现在接受一个可选的 `using` 关键字参数，以控制使用哪个缓存。

- 新的 `truncatechars_html` 过滤器根据指定的字符数截断字符串，考虑到 HTML。

#### 请求和响应

- 新的 `HttpRequest.scheme` 属性指定请求的协议（通常是 `http` 或 `https`）。

- 快捷方式 `redirect()` 现在支持相对 URL。

- `JsonResponse` 是 `HttpResponse` 的一个子类，它可以轻松创建 JSON 编码的响应。

#### 测试

- `DiscoverRunner` 新增了两个属性，`test_suite` 和 `test_runner`，它们有助于重写测试的收集和运行方式。

- `assertRedirects()` 添加了 `fetch_redirect_response` 参数。由于测试客户端无法获取外部 URL，这使您可以在不属于您的 Django 应用程序的重定向上使用 `assertRedirects`。

- 在 `assertRedirects()` 中进行比较时，现在可以正确处理协议。

- `Client` 的所有请求方法现在都添加了 `secure` 参数。如果设置为 `True`，请求将通过 HTTPS 发送。

- 如果断言失败，`assertNumQueries()` 现在会打印出已执行查询的列表。

- 由测试处理程序生成的 `WSGIRequest` 实例现在附加到 `django.test.Response.wsgi_request` 属性。

- 测试的数据库设置已经收集到一个名为 `TEST` 的字典中。

#### 实用程序

- 提高了 `strip_tags()` 的准确性（但如文档中所述，它仍然不能保证产生 HTML 安全的结果）。

#### 验证器

- `RegexValidator` 现在接受可选的 `flags` 和布尔型 `inverse_match` 参数。`inverse_match` 属性确定在正则表达式模式匹配（`True`）或不匹配（默认为 `False`）提供的 `value` 时是否引发 `ValidationError`。`flags` 属性设置编译正则表达式字符串时使用的标志。

- `URLValidator` 现在接受一个可选的 `schemes` 参数，允许自定义接受的 URI 方案（而不是默认的 `http(s)` 和 `ftp(s)`）。

- `validate_email()` 现在接受包含 IPv6 字面量的地址，例如 `example@[2001:db8::1]`，如 RFC 5321 中规定。

## 1.7 版中向后不兼容的变化

Warning

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

### `allow_syncdb` / `allow_migrate`

尽管 Django 仍然会查看 `allow_syncdb` 方法，尽管它们应该重命名为 `allow_migrate`，但传递给这些方法的模型有一些微妙的区别。

对于具有迁移的应用程序，`allow_migrate` 现在将传递 历史模型，这些模型是特殊的带有自定义属性、方法或管理器的版本模型。确保您的 `allow_migrate` 方法只引用了 `model._meta` 中的字段或其他项。

### initial_data

具有迁移的应用程序在完成迁移后将不再加载 `initial_data` 修复程序。没有迁移的应用程序将在模拟旧的 `syncdb` 行为的 `migrate` 阶段继续加载这些修复程序，但任何新的应用程序将不再支持这一功能。

相反，我们鼓励您在需要时在迁移中加载初始数据（使用 `RunPython` 操作和您的模型类）；这有一个附加优势，即每次更改模式时都不需要更新初始数据。

另外，就像 Django 的旧 `syncdb` 代码一样，`initial_data` 也已经开始了弃用路径，并将在 Django 1.9 中移除。

### `deconstruct()` 和可序列化性

Django 现在要求所有 Field 类及其构造函数参数都必须可序列化。如果你以任何方式修改了自定义 Field 的构造函数签名，你需要实现一个 `deconstruct()` 方法；我们已经在自定义字段文档中扩展了 关于实现这个方法的说明。

所有字段参数需要是可 序列化的 要求意味着任何传递到 Field 构造函数中的自定义类实例，比如自定义的 Storage 子类，都需要在它们上面定义一个 deconstruct 方法，尽管 Django 提供了一个方便的类装饰器，对大多数应用都适用。

### 应用加载的变化

#### 启动序列

Django 1.7 在启动时会立即加载应用程序配置和模型。虽然这种行为更为直接，被认为更加健壮，但不能完全排除回归问题。有关您可能遇到的一些问题的解决方案，请参阅 错误调试。

#### 独一无二的脚本

如果你在一个普通的 Python 脚本中使用 Django，而不是管理命令，并且依赖于 `DJANGO_SETTINGS_MODULE` 环境变量，现在你必须在脚本开头显式地初始化 Django，如下所示：

    >>> import django
    >>> django.setup()

否则，你将遇到一个 `AppRegistryNotReady` 异常。

#### WSGI 脚本

在 Django 1.3 之前，创建一个 WSGI 应用程序的推荐方法是：

    import django.core.handlers.wsgi

    application = django.core.handlers.wsgi.WSGIHandler()

在 Django 1.4 中，对 WSGI 的支持得到改进，并且 API 发生了变化：

    from django.core.wsgi import get_wsgi_application

    application = get_wsgi_application()

如果你的 WSGI 脚本仍在使用前一种风格，你需要升级到后一种风格，否则你将遇到一个 `AppRegistryNotReady` 异常。

#### 应用程序注册表的一致性

不再允许安装具有相同标签的多个应用程序。在 Django 的早期版本中，这种情况不总是正常工作，但也不会完全崩溃。

如果你有两个具有相同标签的应用程序，你应该为其中一个创建一个 `AppConfig`，并在其中覆盖其 `label`。然后，你应该在引用该应用程序或其模型的任何代码中，将旧标签调整为新标签。

不再允许通过不同路径两次导入同一模型。从 Django 1.6 开始，只有在手动将一个目录和一个子目录放在 `PYTHONPATH` 上时，才会发生这种情况。有关迁移说明，请参阅 1.4 发布说明中的新项目布局部分。

您应该确保：

- 所有模型都在列在 `INSTALLED_APPS` 中或具有明确 `app_label` 的应用程序中定义。

- 模型不会作为加载其应用程序的副作用而导入。具体而言，您不应该在应用程序的根模块或定义其配置类的模块中导入模型。

从版本 1.9 开始，Django 将强制执行这些要求，经过一段废弃期之后。

#### 继承 AppCommand 类

`AppCommand` 的子类现在必须实现 `handle_app_config()` 方法，而不是 `handle_app()`。这个方法接收一个 `AppConfig` 实例，而不是一个模型模块。

#### 检查应用程序信息

由于 `INSTALLED_APPS` 现在支持应用程序配置类，而不仅仅是应用程序模块，因此你应该检查直接访问此设置的代码，并改为使用应用程序注册表 (`django.apps.apps`)。

应用程序注册表保留了一些旧的应用程序缓存的特性。尽管应用程序缓存是一个私有 API，但过时的方法和参数将通过标准的废弃路径逐步移除，但以下变更将立即生效：

- 当找不到模型时，`get_model` 现在会引发 `LookupError`，而不是返回 `None`。

- `get_model` 和 `get_models` 的 `only_installed` 参数不再存在，`get_model` 的 `seed_cache` 参数也不再存在。

### 管理命令和 `INSTALLED_APPS` 的顺序

当多个应用程序提供具有相同名称的管理命令时，Django 会从 `INSTALLED_APPS` 中排在前面的应用程序加载命令。之前的版本会从排在最后的应用程序加载命令。

这将管理命令的发现与 Django 的其他部分保持一致，这些部分依赖于 `INSTALLED_APPS` 的顺序，比如静态文件、模板和翻译。

### `ValidationError` 构造函数和内部存储

当 `ValidationError` 构造函数接收到错误容器作为参数时（例如，一个 `list` 或一个 `ErrorList`），其行为已经发生了变化：

- 它会在将字符串添加到其内部存储之前，将其转换为 `ValidationError` 的实例。

- 它不会存储给定的容器，而是将其内容复制到自己的内部存储中；以前容器本身被添加到 `ValidationError` 实例并用作内部存储。

这意味着如果你访问 `ValidationError` 的内部存储，比如 `error_list`、`error_dict` 或 `update_error_dict()` 的返回值，你可能会在以前找到字符串的地方找到 `ValidationError` 的实例。

此外，如果你直接将 `update_error_dict()` 的返回值赋给 `Form._errors`，你可能会无意中添加 `list` 实例，而期望的是 `ErrorList` 实例。这是一个问题，因为与简单的 `list` 不同，`ErrorList` 知道如何处理 `ValidationError` 的实例。

现在，大多数需要使用这些私有 API 的用例都可以使用新引入的 `Form.add_error()` 方法来处理：

    # Old pattern:
    try:
        ...
    except ValidationError as e:
        self._errors = e.update_error_dict(self._errors)

    # New pattern:
    try:
        ...
    except ValidationError as e:
        self.add_error(None, e)

如果你需要同时兼容 Django <= 1.6 和 1.7，由于在 Django 1.7 之前没有提供 `Form.add_error()` 方法，你可以使用以下解决方法将任何 `list` 转换为 `ErrorList`：

    try:
        ...
    except ValidationError as e:
        self._errors = e.update_error_dict(self._errors)

    # Additional code to ensure ``ErrorDict`` is exclusively
    # composed of ``ErrorList`` instances.
    for field, error_list in self._errors.items():
        if not isinstance(error_list, self.error_class):
            self._errors[field] = self.error_class(error_list)

### 关于 `LocMemCache` 对 pickle 错误的行为

在以前的 Django 版本中存在一个不一致之处，关于不同缓存后端如何处理 pickle 错误。`django.core.cache.backends.locmem.LocMemCache` 以前在发生这种错误时会静默失败，这与其他后端不一致，并导致了与缓存相关的错误。在 Django 1.7 中已经修复了这个问题，详情请参阅 #21200。

### 现在缓存键从请求的绝对 URL 生成

在以前的 Django 版本中，缓存键是使用请求的路径和查询字符串生成的，但不包括 scheme 和 host。如果一个 Django 应用程序服务多个子域或域名，缓存键可能会发生冲突。在 Django 1.7 中，缓存键会根据请求的绝对 URL 包括 scheme、host、path 和查询字符串而变化。例如，缓存键的 URL 部分现在是从 `https://www.example.com/path/to/?key=val` 生成的，而不是 `/path/to/?key=val`。Django 1.7 生成的缓存键将与旧版本的 Django 生成的键不同。升级到 Django 1.7 后，对任何以前缓存的 URL 的第一个请求将导致缓存未命中。

### 将 `None` 传递给 `Manager.db_manager()`

在以前的 Django 版本中，可以在模型管理器实例上使用 `db_manager(using=None)` 来获取一个使用默认路由行为的管理器实例，覆盖任何手动指定的数据库路由。在 Django 1.7 中，传递给 db_manager 的值为 `None` 将产生一个保留任何手动分配的数据库路由的路由器 -- 管理器将 不 被重置。这是为了解决路由信息在连接中级联的方式存在的不一致性。详情请参阅 #13724。

### 可能需要使用 `pytz`

如果你的项目处理 1970 年之前或 2037 年之后的日期时间，并且当 Django 遇到它们时引发 `ValueError`，那么你将需要安装 pytz。如果你使用了 Django 的时区相关的日期格式或 `django.contrib.syndication`，可能会受到这个问题的影响。

### 关于相关管理器的 `remove()` 和 `clear()` 方法

`ForeignKey`、`GenericForeignKey` 和 `ManyToManyField` 创建的相关管理器的 `remove()` 和 `clear()` 方法存在一些问题。一些操作在没有包装在事务中的情况下运行多个数据修改查询，而一些操作在存在默认过滤条件时（即当相关模型上的默认管理器实现了自定义的 `get_queryset()` 时）不会尊重默认过滤条件。

修复这些问题引入了一些向后不兼容的更改：

- `ForeignKey` 相关管理器的默认 `remove()` 实现从一系列的 `Model.save()` 调用更改为单个 `QuerySet.update()` 调用。这个改变意味着不再发送 `pre_save` 和 `post_save` 信号。你可以使用 `bulk=False` 关键字参数来恢复到以前的行为。

- `GenericForeignKey` 相关管理器的 `remove()` 和 `clear()` 方法现在执行批量删除。不再在每个实例上调用 `Model.delete()` 方法。你可以使用 `bulk=False` 关键字参数来恢复到以前的行为。

- 与 `ManyToManyField` 相关的管理器的 `remove()` 和 `clear()` 方法在涉及到过滤时执行嵌套查询，这可能会根据你的数据库和数据本身是否成问题而有所不同。有关更多详情，请参阅 此说明。

### 管理员登录重定向策略

在历史上，Django 管理站点会将未经授权或未经身份验证的用户的请求直接传递给登录视图，而不进行 HTTP 重定向。在 Django 1.7 中，这种行为发生了变化，以符合更传统的工作流程，其中任何未经授权的请求到管理页面都会被重定向（通过 HTTP 状态码 302）到登录页面，其中 `next` 参数设置为引用的路径。用户在成功登录后将被重定向到那里。

还请注意，管理员登录表单已更新，不再包含无用的 `this_is_the_login_form` 字段，而且 `ValidationError` 代码已设置为更常规的 `invalid_login` 键。

### `select_for_update()` 需要在事务中使用

Historically, queries that use `select_for_update()` could be executed in autocommit mode, outside of a transaction. Before Django 1.6, Django's automatic transactions mode allowed this to be used to lock records until the next write operation. Django 1.6 introduced database-level autocommit; since then, execution in such a context voids the effect of `select_for_update()`. It is, therefore, assumed now to be an error and raises an exception.

这个更改是因为这样的错误可能是由包含一个期望全局事务的应用程序（例如：`ATOMIC_REQUESTS` 设置为 `True`）或者 Django 的旧的自动提交行为，在一个不需要它们的项目中运行时引起的；而且，这样的错误可能会表现为数据损坏的问题。这个更改也是在 Django 1.6.3 中进行的。

如果您在测试类中使用 `select_for_update()` 并且该测试类是 `TransactionTestCase` 的子类而不是 `TestCase`，则此更改可能导致测试失败。

### Contrib 中间件从默认的 `MIDDLEWARE_CLASSES` 中移除

应用加载重构 弃用了使用不在 `INSTALLED_APPS` 设置中的应用程序中的模型。这暴露出默认的 `INSTALLED_APPS` 和全局默认值（`django.conf.global_settings`）中的 `MIDDLEWARE_CLASSES` 之间的不兼容性。为了使这些设置保持同步，并且在使用最小设置测试可重用应用程序等情况下防止弃用警告，从默认设置中移除了 `SessionMiddleware`、`AuthenticationMiddleware` 和 `MessageMiddleware`。这些类仍然会包含在由 `startproject` 生成的默认设置中。大多数项目不会受到这个更改的影响，但如果你之前没有在项目设置中声明 `MIDDLEWARE_CLASSES` 并依赖于全局默认值，你应该确保新的默认值符合你的项目需求。你还应该检查任何访问 `django.conf.global_settings.MIDDLEWARE_CLASSES` 的代码。

### 杂项

- The `django.core.files.uploadhandler.FileUploadHandler.new_file()` method is now passed an additional `content_type_extra` parameter. If you have a custom `FileUploadHandler` that implements `new_file()`, be sure it accepts this new parameter.

- `ModelFormSet` 在调用 `save(commit=False)` 时不再删除实例。请查看 `can_delete` 以获取如何手动从删除的表单中删除对象的说明。

- 加载空的 fixture 现在会发出一个 `RuntimeWarning`，而不是引发 `CommandError`。

- 当 `DEBUG` 为 `False` 时，`django.contrib.staticfiles.views.serve()` 现在会引发一个 `Http404` 异常，而不是 `ImproperlyConfigured`。这个更改消除了将视图有条件地添加到根 URLconf 的需要，从而使其能够通过名称安全地反转。它还消除了访问者通过请求不存在或尚未收集的静态文件而生成虚假的 HTTP 500 错误的能力。

- `django.db.models.Model.__eq__()` 方法现在以一种新的方式定义，其中代理模型的实例和其基模型的实例在主键匹配时被视为相等。以前，只有完全相同类的实例在主键匹配时被视为相等。

- `django.db.models.Model.__eq__()` 方法已更改，因此两个没有主键值的 `Model` 实例不会被视为相等（除非它们是同一个实例）。

- 当在没有主键值的实例上调用 `django.db.models.Model.__hash__()` 方法时，现在会引发 `TypeError`。这是为了避免在容器中使用可变的 `__hash__` 值。

- 在 SQLite 数据库中，`AutoField` 列现在将使用 `AUTOINCREMENT` 选项创建，以确保单调递增。这将导致 SQLite 上的主键编号行为发生变化，与大多数其他 SQL 数据库保持一致。这仅适用于新创建的表。如果你有一个使用较早版本的 Django 创建的数据库，你需要迁移它以利用这个功能。例如，你可以执行以下操作：

  1. 使用 `dumpdata` 来保存你的数据。

  2. 重命名现有的数据库文件（将其保留作为备份）。

  3. 运行 `migrate` 来创建更新后的模式。

  4. 使用 `loaddata` 导入你在第一步导出的 fixture 数据。

- `django.contrib.auth.models.AbstractUser` no longer defines a `get_absolute_url()` method. The old definition returned `"/users/%s/" % urlquote(self.username)` which was arbitrary since applications may or may not define such a url in `urlpatterns`. Define a `get_absolute_url()` method on your own custom user object or use `ABSOLUTE_URL_OVERRIDES` if you want a URL for your user.

- `django.test.LiveServerTestCase` 类的静态资源服务功能已经简化：现在它只能在运行测试时服务于已经存在于 `STATIC_ROOT` 中的内容。像在开发时使用 `DEBUG = True` 那样透明地提供所有静态资源的能力已经移动到一个新的类中，该类位于 `staticfiles` 应用程序中（实际负责此功能的应用程序）：`django.contrib.staticfiles.testing.StaticLiveServerTestCase`。换句话说，`LiveServerTestCase` 本身的功能减弱了，但同时也减少了魔法。

  这样做的原因是将非 contrib 代码与 contrib 应用程序的依赖关系移除。

- 旧的缓存 URI 语法（例如 `"locmem://"`）不再受支持。尽管它之前可以工作，但它并没有被记录或正式支持。如果你仍在使用它，请更新到当前的 `CACHES` 语法。

- 在继承情况下，`Form` 字段的默认排序方式已更改为遵循正常的 Python MRO。现在，字段是通过反向迭代 MRO 来发现的，最顶层的类最后被考虑。这只会在你同时在当前类和父类 `Form` 中定义字段并且依赖于默认字段顺序时影响你。

- `SelectDateWidget` 的 `required` 参数已被移除。这个小部件现在会像其他小部件一样尊重表单字段的 `is_required` 属性。

- `Widget.is_hidden` 现在是一个只读属性，通过检查 `input_type == 'hidden'` 的存在来获取其值。

- `select_related()` 现在与其他类似的调用（如 `prefetch_related`）以相同的方式链式调用。也就是说，`select_related('foo', 'bar')` 等同于 `select_related('foo').select_related('bar')`。以前，后者等同于 `select_related('bar')`。

- GeoDjango 不再支持 GEOS < 3.1 。

- 数据库后端的 `init_connection_state` 方法现在在自动提交模式下执行（除非你将 `AUTOCOMMIT` 设置为 `False`）。如果你维护一个自定义数据库后端，你应该检查这个方法。

- `django.db.backends.BaseDatabaseFeatures.allows_primary_key_0` 属性已重命名为 `allows_auto_pk_0`，以更好地描述它。对于所有包含在 Django 中的数据库后端，除了 MySQL，它都为 `True`，因为 MySQL 允许主键值为 0。它只禁止具有值 0 的 autoincrement 主键。

- 禁止在子模型中定义与父模型中已定义的字段同名的字段，因为这会导致模型行为的歧义。此外，在模型继承层次结构中发生字段冲突将导致系统检查错误。例如，如果使用多继承，你需要在父模型中定义自定义主键字段，否则默认的 `id` 字段将发生冲突。有关详细信息，请参阅 多重继承。

- `django.utils.translation.parse_accept_lang_header()` 现在返回小写的区域设置，而不是提供的大小写。由于区域设置应该被视为不区分大小写，这使得我们能够加速区域设置的检测。

- `django.utils.translation.get_language_from_path()` 和 `django.utils.translation.trans_real.get_supported_language_variant()` 现在不再接受 `supported` 参数。

- `django.contrib.contenttypes.views` 中的 `shortcut` 视图现在支持协议相对 URL（例如 `//example.com`）。

- `GenericRelation` 现在支持一个可选的 `related_query_name` 参数。设置 `related_query_name` 可以在相关对象和内容类型之间添加关系，用于过滤、排序和其他查询操作。

- 在 PostgreSQL 上运行测试时，`USER` 将需要对内置的 `postgres` 数据库进行读取访问权限。这是替代了以前连接到实际非测试数据库的行为。

- 作为 系统检查框架 的一部分，字段、模型和模型管理器 都实现了一个已在检查框架中注册的 `check()` 方法。如果你已经在其中一个对象上有一个名为 `check()` 的现有方法，你需要将其重命名。

- 如上述 "缓存" 部分所提到的，将 `CACHES` 设置的 `TIMEOUT` 参数定义为 `None` 将设置缓存键为 "不过期"。以前，对于 memcache 后端，`TIMEOUT` 为 `0` 会设置不过期的键，但这与 `set("key", "value", timeout=0)` 的设置和过期（即不缓存）行为不一致。如果你想要不过期的键，请更新你的设置，将 `0` 改为 `None`，因为后者现在在设置中也表示设置和过期。

- `sql*` 管理命令现在尊重 `DATABASE_ROUTERS` 的 `allow_migrate()` 方法。如果你的模型与非默认数据库同步，请使用 `--database` 标志来获取这些模型的 SQL（以前它们总是包含在输出中）。

- 解码 URL 中的查询字符串现在在输入不是有效的 UTF-8 时会回退到 ISO-8859-1 编码。

- 通过将 `django.contrib.auth.middleware.SessionAuthenticationMiddleware` 添加到默认项目模板（仅适用于 1.7.2 之前的版本），在使用 `runserver` 访问页面之前必须创建一个数据库。

- 将 `schemes` 参数添加到 `URLValidator` 中可能会在你之前使用自定义正则表达式来验证 schemes 的情况下出现向后不兼容的更改。如果 schemes 中没有列出的任何 scheme 将失败验证，即使正则表达式匹配给定的 URL。

## 在 1.7 中被废弃的功能

### `django.core.cache.get_cache`

`django.core.cache.get_cache` 已被 `django.core.cache.caches` 取代。

### `django.utils.dictconfig`/`django.utils.importlib`

`django.utils.dictconfig` 和 `django.utils.importlib` 分别是在 Python 版本 2.7 之前提供的 `logging.config` 和 `importlib` 的副本。它们已经被弃用。

### `django.utils.module_loading.import_by_path`

当前的 `django.utils.module_loading.import_by_path` 函数捕获 `AttributeError`、`ImportError` 和 `ValueError` 异常，并重新引发 `ImproperlyConfigured` 异常。这种异常掩盖使得诊断循环导入问题变得不必要地困难，因为它让问题看起来像是来自 Django 内部。它已被弃用，推荐使用 `import_string()`。

### `django.utils.tzinfo`

`django.utils.tzinfo` 提供了两个 `tzinfo` 的子类，分别是 `LocalTimezone` 和 `FixedOffset`。它们已经被弃用，推荐使用更正确的替代方案，由 `django.utils.timezone` 提供的 `django.utils.timezone.get_default_timezone()` 和 `django.utils.timezone.get_fixed_timezone()`。

### `django.utils.unittest`

`django.utils.unittest` 在所有 Python 版本上提供了对 `unittest2` 库的统一访问。由于 `unittest2` 在 Python 2.7 中成为标准库的 `unittest` 模块，并且 Django 1.7 不再支持旧的 Python 版本，因此该模块不再有用。它已被弃用，请改用 `unittest`。

### `django.utils.datastructures.SortedDict`

由于 Python 2.7 中已经添加了 `OrderedDict` 到标准库中，因此不再需要 `SortedDict`，它已经被弃用。

`SortedDict` 提供的两个额外且已弃用的方法（`insert()` 和 `value_for_index()`）已被移除。如果您曾依赖这些方法来更改类似表单字段的结构，现在应将这些 `OrderedDict` 视为不可变对象，并重写它们以更改其内容。

例如，您可能希望覆盖 `MyFormClass.base_fields` （尽管该属性不被视为公共 API）以更改所有 `MyFormClass` 实例的字段顺序；或者类似地，您可以在 `MyFormClass.__init__()` 中从内部覆盖 `self.fields`，以更改特定表单实例的字段。例如（来自 Django 自身）：

    PasswordChangeForm.base_fields = OrderedDict(
        (k, PasswordChangeForm.base_fields[k])
        for k in ["old_password", "new_password1", "new_password2"]
    )

### 自定义模型包的 SQL 位置

以前，如果模型组织在一个包中（`myapp/models/`）而不是简单的 `myapp/models.py`，Django 会在 `myapp/models/sql/` 中查找初始 SQL 数据。这个问题已经被修复，Django 将按文档中的方式搜索 `myapp/sql/`。在解决了这个问题后，添加了迁移，从而废弃了初始 SQL 数据。因此，尽管这个改变仍然存在，但废弃已经不相关，因为整个功能将在 Django 1.9 中被移除。

### `django.contrib.sites` 的重新组织

当 `django.contrib.sites` 不在 `INSTALLED_APPS` 中时，它提供的功能会减少。应用程序加载的重构在这种情况下添加了一些限制。因此，两个对象被移动，旧的位置已被弃用：

- `RequestSite` 现在位于 `django.contrib.sites.requests` 中。

- `get_current_site()` 现在位于 `django.contrib.sites.shortcuts` 中。

### `ModelAdmin` 上的 `declared_fieldsets` 属性

`ModelAdmin.declared_fieldsets` 已经被弃用。尽管它是一个私有 API，但它将按照常规的弃用路径进行处理。这个属性主要被一些绕过了 `ModelAdmin.get_fieldsets()` 方法的方法使用，但这被视为一个错误，并已得到解决。

### `django.contrib.contenttypes` 的重新组织

由于 `django.contrib.contenttypes.generic` 定义了与管理和模型相关的对象，导入该模块可能会触发意外的副作用。因此，其内容已被拆分为 `contenttypes` 子模块，并且 `django.contrib.contenttypes.generic` 模块已被弃用：

- `GenericForeignKey` 和 `GenericRelation` 现在位于 `fields` 中。

- `BaseGenericInlineFormSet` 和 `generic_inlineformset_factory()` 现在位于 `forms` 中。

- `GenericInlineModelAdmin`、`GenericStackedInline` 和 `GenericTabularInline` 现在位于 `admin` 中。

### `syncdb`

`syncdb` 命令已被弃用，推荐使用新的 `migrate` 命令。`migrate` 命令接受与以前的 `syncdb` 相同的参数，还添加了一些额外的参数，因此只需更改调用的名称而不需要做其他更改。

### `util` 模块已重命名为 `utils`

在 Django 代码库中，以下实例的 `util.py` 已重命名为 `utils.py`，以统一所有 util 和 utils 的引用：

- `django.contrib.admin.util`

- `django.contrib.gis.db.backends.util`

- `django.db.backends.util`

- `django.forms.util`

### 在 `ModelAdmin` 上的 `get_formsets` 方法

`ModelAdmin.get_formsets` 已弃用，推荐使用新的 `get_formsets_with_inlines()`，以更好地处理在 `ModelAdmin` 上有选择地显示内联表单的情况。

### `IPAddressField`

`django.db.models.IPAddressField` 和 `django.forms.IPAddressField` 字段已弃用，推荐使用 `django.db.models.GenericIPAddressField` 和 `django.forms.GenericIPAddressField`。

### `BaseMemcachedCache._get_memcache_timeout` 方法

`BaseMemcachedCache._get_memcache_timeout()` 方法已重命名为 `get_backend_timeout()`。尽管它是一个私有 API，但它将经历正常的弃用过程。

### 自然键序列化选项

`--natural` 和 `-n` 选项对于 `dumpdata` 已被弃用。请改用 `dumpdata --natural-foreign`。

类似地，对于 `serializers.serialize()` 的 `use_natural_keys` 参数已被弃用。请改用 `use_natural_foreign_keys`。

### 将 `POST` 和 `GET` 参数合并到 `WSGIRequest.REQUEST` 中

已经强烈建议使用 `GET` 和 `POST` 而不是 `REQUEST`，因为前者更加明确。属性 `REQUEST` 已弃用，并将在 Django 1.9 中移除。

### `django.utils.datastructures.MergeDict` 类

`MergeDict` 主要用于将 `POST` 和 `GET` 参数合并到 `WSGIRequest` 上的 `REQUEST` 属性中。要合并字典，请使用 `dict.update()`。类 `MergeDict` 已被弃用，并将在 Django 1.9 中移除。

### 语言代码 `zh-cn`、`zh-tw` 和 `fy-nl`

目前用于简体中文的语言代码 `zh-cn`，繁体中文的语言代码 `zh-tw` 和 (西弗里西亚) 弗里西亚语的语言代码 `fy-nl` 已被弃用，应分别替换为语言代码 `zh-hans`，`zh-hant` 和 `fy`。如果您使用这些语言代码，应重命名区域目录并更新您的设置以反映这些更改。弃用的语言代码将在 Django 1.9 中移除。

### `django.utils.functional.memoize` 函数

函数 `memoize` 已被弃用，应替换为 `functools.lru_cache` 装饰器（从 Python 3.2 开始可用）。

Django 在较旧的 Python 版本中附带了这个装饰器的后移版本，并且可以在 `django.utils.lru_cache.lru_cache` 中使用。弃用的函数将在 Django 1.9 中移除。

### 地理网站地图

Google 已停止支持 Geo Sitemaps 格式。因此，Django 对 Geo Sitemaps 的支持已被弃用，并将在 Django 1.8 中移除。

### 将可调用参数传递给查询集方法

查询集的可调用参数是一个未记录的功能，不可靠。已弃用，并将在 Django 1.9 中移除。

可调用参数在构建查询集时被求值，而不是在查询集被评估时求值，因此与在传递参数之前对其进行求值相比，此功能并没有提供任何好处，并且会导致混淆，使人误以为参数可能在查询时被求值。

### `ADMIN_FOR` 设置

`ADMIN_FOR` 功能，是 admindocs 的一部分，已被移除。您可以根据需要从配置中移除此设置。

### `SplitDateTimeWidget` 与 `DateTimeField`

`SplitDateTimeWidget` 在 `DateTimeField` 上的支持已被弃用，请改用与 `SplitDateTimeField` 一起使用的 `SplitDateTimeWidget`。

### `validate`

`validate` 管理命令已被弃用，推荐使用 `check` 命令。

### `django.core.management.BaseCommand`

`requires_model_validation` 已被弃用，改为使用新的 `requires_system_checks` 标志。如果缺少后者标志，则将使用前者标志的值。定义同时 `requires_system_checks` 和 `requires_model_validation` 将导致错误。

`check()` 方法取代了旧的 `validate()` 方法。

### `ModelAdmin` 验证器

`ModelAdmin.validator_class` 和 `default_validator_class` 属性已被弃用，推荐使用新的 `checks_class` 属性。

`ModelAdmin.validate()` 方法已被弃用，推荐使用 `ModelAdmin.check()`。

`django.contrib.admin.validation` 模块已被弃用。

### `django.db.backends.DatabaseValidation.validate_field`

这个方法已被弃用，推荐使用新的 `check_field` 方法。`check_field()` 所需的功能与 `validate_field()` 提供的相同，但输出格式不同。需要这种功能的第三方数据库后端应提供 `check_field()` 的实现。

### 从 `future` 库加载 `ssi` 和 `url` 模板标签

Django 1.3 引入了 `{% load ssi from future %}` 和 `{% load url from future %}` 语法，用于前向兼容 `ssi` 和 `url` 模板标签。这个语法现在已被弃用，并将在 Django 1.9 中移除。您可以简单地删除 `{% load ... from future %}` 标签。

### `django.utils.text.javascript_quote`

`javascript_quote()` 是一个位于 `django.utils.text` 中的未记录函数。它在 `javascript_catalog()` 视图的内部使用，但该视图的实现已更改为使用 `json.dumps()`。如果您依赖此函数来提供来自不受信任的字符串的安全输出，您应该使用 `django.utils.html.escapejs` 或 `escapejs` 模板过滤器。如果您只需要生成有效的 JavaScript 字符串，可以简单地使用 `json.dumps()`。

### `fix_ampersands` 工具方法和模板过滤器

`django.utils.html.fix_ampersands` 方法和 `fix_ampersands` 模板过滤器已被弃用，因为 Django 的标准 HTML 转义功能已经处理了 ampersands 的转义。与 `fix_ampersands` 结合使用可能会导致重复转义，或者如果输出被视为安全，则存在引入 XSS 漏洞的风险。除了 `fix_ampersands`，未记录的调用 `fix_ampersands` 的 `django.utils.html.clean_html` 也已被弃用。由于这是一项加速弃用，`fix_ampersands` 和 `clean_html` 将在 Django 1.8 中移除。

### 数据库测试设置的重新组织

所有以 `TEST_` 前缀的数据库设置已被弃用，推荐使用数据库设置中的 `TEST` 字典中的条目。旧设置将在 Django 1.9 之前受到支持。为了与较旧版本的 Django 向后兼容，您可以定义这两个版本的设置，只要它们匹配即可。

### FastCGI 支持

通过 `runfcgi` 管理命令提供的 FastCGI 支持将在 Django 1.9 中移除。请使用 WSGI 部署您的项目。

### `contrib.sites` 中的对象已移动

在应用加载重构后，`django.contrib.sites.models` 中的两个对象需要移动，因为它们在没有安装 `django.contrib.sites` 的情况下必须可用，而无需导入 `django.contrib.sites.models`。从 `django.contrib.sites.requests` 导入 `RequestSite`，从 `django.contrib.sites.shortcuts` 导入 `get_current_site()`。旧的导入位置将在 Django 1.9 之前继续工作。

### `django.forms.forms.get_declared_fields()`

Django 不再在内部使用此功能。尽管它是一个私有 API，但它将按照正常的弃用周期进行处理。

### 私有查询查找 API

私有 API `django.db.models.sql.where.WhereNode.make_atom()` 和 `django.db.models.sql.where.Constraint` 已被弃用，推荐使用新的 自定义查询 API。

## 在 1.7 版本中移除的功能

这些功能已经完成了它们的弃用周期，并在 Django 1.7 中被移除。有关详细信息，包括如何删除对这些功能的使用，请参阅 在 1.5 中被废弃的功能。

- `django.utils.simplejson` 已被移除。

- `django.utils.itercompat.product` 已被移除。

- INSTALLED_APPS 和 TEMPLATE_DIRS 不再自动将纯字符串转换为元组。

- `HttpResponse`、`SimpleTemplateResponse`、`TemplateResponse`、`render_to_response()`、`index()` 和 `sitemap()` 不再接受 `mimetype` 参数。

- `HttpResponse` 如果其内容是一个迭代器，会立即消耗它。

- `AUTH_PROFILE_MODULE` 设置以及用户模型上的 `get_profile()` 方法已被移除。

- `cleanup` 管理命令已被移除。

- `daily_cleanup.py` 脚本已被移除。

- `select_related()` 不再具有 `depth` 关键字参数。

- 从 `django.test.utils` 中的 `get_warnings_state()`/`restore_warnings_state()` 函数以及 django.test.*TestCase 中的 `save_warnings_state()`/ `restore_warnings_state()` 已被移除。

- `AuthenticationForm` 中的 `check_for_test_cookie` 方法已被移除。

- 支持 base36 编码的用户 ID 的 `django.contrib.auth.views.password_reset_confirm()` 版本（`django.contrib.auth.views.password_reset_confirm_uidb36`）已被移除。

- `django.utils.encoding.StrAndUnicode` 混合类已被移除。