---
title: "Django 1.1 版本发行说明"
version: 6.1
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/6.1/releases/1.1/
canonical: https://djangodocs.dev/zh-hans/6.1/releases/1.1/
---
# Django 1.1 版本发行说明

2009 年 7 月 29 日

欢迎来到 Django 1.1 版本！

Django 1.1 包含了许多 [新功能](#whats-new-1-1)、大量的 bug 修复，以及从 Django 1.0 升级的简便路径。

## 1.1 中的不向后兼容的变更

Django 具有一项 [API 稳定性](/zh-hans/6.1/misc/api-stability/) 的政策。这意味着通常情况下，你在 Django 1.0 上开发的代码应该可以在 1.1 上无需修改继续运行。然而，如果需要解决 bug，我们有时会进行不兼容的变更，而在 Django 1.0 和 Django 1.1 之间存在一些这样的（小的）变更。

在升级到 Django 1.1 之前，你应该仔细检查以下更改是否会影响你的代码，并在需要时进行代码升级。

### 约束名称的更改

Django 1.1 修改了生成数据库约束名称的方法，使得名称在不同机器字长下保持一致。这个改变对一些用户来说是不兼容的。

如果你使用的是 32 位平台，你就不用担心了；你不会因为这个改变而观察到任何差异。

然而，**在 64 位平台上的用户可能会在使用 \`\`reset\`\` 管理命令时遇到一些问题**。在这个更改之前，64 位平台会生成一个 64 位、16 个字符的约束名称；例如：

```sql
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN KEY ...
```

在这个改变之后，所有平台（无论字长如何）都将在约束名称中生成一个 32 位、8 个字符的摘要；例如：

```sql
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...
```

由于这个更改，你将无法在由 64 位机器创建的任何表上使用 `reset` 管理命令。这是因为新生成的名称将不匹配历史生成的名称；因此，reset 命令构建的 SQL 将无效。

如果你需要重置一个使用 64 位约束创建的应用程序，你需要在调用 `reset` 命令之前手动删除旧的约束。

### 现在测试用例在一个事务中运行

Django 1.1 在事务内运行测试，从而提高了测试性能（详细信息请参见 [测试性能改进](#test-performance-improvements)）。

如果现有的测试需要测试事务行为，如果它们依赖于对测试环境的无效假设，或者如果它们需要特定的测试用例顺序，那么这个改变在某种程度上是不兼容的。

对于这些情况，可以使用 [`TransactionTestCase`](/zh-hans/6.1/topics/testing/tools/#django.test.TransactionTestCase)。这只是一个快速的修复方法，用来解决新的回滚方式暴露出的测试用例错误；从长远来看，应该重新编写测试用例以纠正问题。

### 移除了 `SetRemoteAddrFromForwardedFor` 中间件

为了方便，Django 1.0 包括了一个可选的中间件类 -- `django.middleware.http.SetRemoteAddrFromForwardedFor` -- 该类基于一些代理配置常常设置的 HTTP `X-Forwarded-For` 头部更新了 `REMOTE_ADDR` 的值。

已经证明这个机制不能够可靠到足以用于通用用途，并且（尽管文档中有不同的说明）它包含在 Django 中可能会导致应用程序开发者假设 `REMOTE_ADDR` 的值是“安全的”或以某种方式可靠作为身份验证的来源。

尽管这不是一个直接的安全问题，但我们决定在 Django 1.1 版本中删除这个中间件。它已被替换为一个什么都不做，只会引发 `DeprecationWarning` 的类。

如果你一直依赖这个中间件，最简单的升级路径是：

- 检查 [在被移除之前的代码](https://github.com/django/django/blob/91f18400cc0fb37659e2dbaab5484ff2081f1f30/django/middleware/http.py#L33)。
- 验证它是否与你的上游代理正确工作，并根据需要修改以支持你的特定代理。
- 在你自己的项目中将我修改过的版本的 `SetRemoteAddrFromForwardedFor` 作为中间件引入。

### 上传文件的名称稍后可用

在 Django 1.0 中，上传并存储在模型的 [`FileField`](/zh-hans/6.1/ref/models/fields/#django.db.models.FileField) 中的文件在模型保存到数据库之前会被保存到磁盘。这意味着在保存之前可以获取分配给文件的实际文件名。例如，在模型的预保存信号处理程序中可以获取到它。

在 Django 1.1 中，文件会作为保存模型到数据库的一部分而被保存，因此在模型被保存之前不能依赖于磁盘上使用的实际文件名。

### 模型表单集的保存方式的变更

在Django 1.1中，`save()`。

如果你在模型表单集的 `__init__` 中修改了 `self.initial`，或者依赖于 BaseFormSet 的内部属性 `_total_form_count` 或 `_initial_form_count`，这是不兼容的。现在这些属性已经变成了公共方法。

### 修复了"join"过滤器的转义行为

[`join`](/zh-hans/6.1/ref/templates/builtins/#std-templatefilter-join) 过滤器不再转义传递给连接器的字面量。

这对于包含五个特殊 HTML 字符之一的文字字符串的特殊情况是不兼容的。因此，如果你之前写的是 `{{ foo|join:"&" }}`，现在你必须写成 `{{ foo|join:"&amp;" }}`。

先前的行为是一个错误，并且与所记录和预期的不符。

### 永久重定向和\`redirect\_to()\`通用视图

Django 1.1 在 `django.views.generic.simple.redirect_to()` 视图中添加了一个 `permanent` 参数。如果你使用 `redirect_to` 视图并将格式字符串键命名为 'permanent'，这在技术上是向后不兼容的，这是极不可能的。

## 在 1.1 中被废弃的功能

在 Django 1.1 中，一个功能已被标记为废弃。

- 你不应再使用 `AdminSite.root()` 来注册管理员视图。也就是说，如果你的 URL 配置包含以下行：

  ```
  (r"^admin/(.*)", admin.site.root),
  ```

  你应该将其修改为如下所示：

  ```
  (r"^admin/", include(admin.site.urls)),
  ```

你应立即开始从你的代码中移除对该功能的使用。

在 Django 1.1 中，如果使用 `AdminSite.root`，将会引发一个 `PendingDeprecationWarning` 警告，默认情况下这个警告是隐藏的。在 Django 1.2 中，这个警告将升级为 `DeprecationWarning`，并且会被明显显示出来。在 Django 1.3 中，将完全删除 `AdminSite.root()`。

有关我们的废弃政策和策略的更多详细信息，请参阅 [Django 的发行流程](/zh-hans/6.1/internals/release-process/)。

## Django 1.1 中的新功能有哪些？

相当多：自 Django 1.0 以来，我们进行了 1290 次代码提交，修复了 1206 个错误，并增加了大约 10000 行文档。

Django 1.1 的主要新功能有：

### ORM 改进

Django 的对象关系映射器（ORM）已经增加了两个重要的增强功能：聚合支持和查询表达式。

#### 聚合支持

现在可以从 Django 的 ORM 中运行 SQL 聚合查询（例如 `COUNT()`、`MAX()`、`MIN()` 等）。你可以选择直接返回聚合的结果，或者在 [`QuerySet`](/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet) 中使用聚合查询的结果来注释对象。

这个功能可以通过新的 [`aggregate()`](/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.aggregate) 和 [`annotate()`](/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.annotate) 方法来使用，详细信息可以在 [ORM 聚合文档](/zh-hans/6.1/topics/db/aggregation/) 中找到。

#### 查询表达式

现在查询可以引用查询中的另一个字段，并且可以遍历关系引用相关模型上的字段。这是通过新的 [`F`](/zh-hans/6.1/ref/models/expressions/#django.db.models.F) 对象实现的；有关完整的详细信息，包括示例，请查阅 [`F 表达式文档`](/zh-hans/6.1/ref/models/expressions/#django.db.models.F)。

### 模型改进

Django 的模型层已添加了多项功能：

#### "未管理"模型

现在，你可以使用 [`managed`](/zh-hans/6.1/ref/models/options/#django.db.models.Options.managed) 模型选项来控制 Django 是否管理模型的数据库表的生命周期。默认值是 `True`，这意味着 Django 将在 `syncdb` 中创建相应的数据库表，并在 `reset` 命令中删除它们。换句话说，Django *管理* 数据库表的生命周期。

然而，如果将其设置为 `False`，则不会自动执行该模型的数据库表创建或删除操作。如果该模型代表已存在的表格或者是由其他方式创建的数据库视图，这会很有用。

更多详细信息，请查看 [`managed`](/zh-hans/6.1/ref/models/options/#django.db.models.Options.managed) 选项的文档。

#### 代理模型

现在你可以创建 [代理模型](/zh-hans/6.1/topics/db/models/#proxy-models)：这些是现有模型的子类，只添加 Python 级别（而不是数据库级别）的行为，并且不代表一个新的表格。也就是说，新模型是某个底层模型的 *代理*，而底层模型存储了所有真实数据。

所有详细信息可以在 [代理模型文档](/zh-hans/6.1/topics/db/models/#proxy-models) 中找到。这个功能在表面上与未管理的模型相似，因此文档中有一个解释 [代理模型与未管理模型的不同之处](/zh-hans/6.1/topics/db/models/#proxy-vs-unmanaged-models)。

#### 延迟字段

在某些复杂情况下，你的模型可能包含大量数据的字段（例如，大型文本字段），或者需要耗费大量计算资源将其转换为 Python 对象。如果你确定不需要这些特定字段，现在可以告诉 Django 不从数据库中检索它们。

你可以使用新的查询集方法 [`defer()`](/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.defer) 和 [`only()`](/zh-hans/6.1/ref/models/querysets/#django.db.models.query.QuerySet.only) 来实现这一点。

### 测试改进

[测试框架](/zh-hans/6.1/topics/testing/) 中已经进行了一些显著的改进。

#### 测试性能改进

使用 Django 的 [测试框架](/zh-hans/6.1/topics/testing/) 编写的测试现在运行速度大幅提高（在许多情况下提高了多达 10 倍）。

通过引入基于事务的测试来实现的：当使用 [`django.test.TestCase`](/zh-hans/6.1/topics/testing/tools/#django.test.TestCase) 时，你的测试现在将在一个事务中运行，测试结束后将回滚事务，而不是刷新和重新填充数据库。这对于大多数类型的单元测试来说会极大地提速。请查看 [`TestCase`](/zh-hans/6.1/topics/testing/tools/#django.test.TestCase) 和 [`TransactionTestCase`](/zh-hans/6.1/topics/testing/tools/#django.test.TransactionTestCase) 的文档以获取完整的描述，以及关于数据库支持的一些重要说明。

### 测试客户端改进

测试客户端进行了几项小而非常有用的改进：

- 测试中的 [`Client`](/zh-hans/6.1/topics/testing/tools/#django.test.Client) 现在可以通过 [`Client.get()`](/zh-hans/6.1/topics/testing/tools/#django.test.Client.get) 和 [`Client.post()`](/zh-hans/6.1/topics/testing/tools/#django.test.Client.post) 的 `follow` 参数自动跟随重定向。这使得测试发出重定向的视图更加简单。
- 现在更容易获取测试客户端返回的响应中的模板上下文：你只需将上下文作为 `request.context[key]` 来访问。如果需要，仍然可以使用旧方式，该方式将 `request.context` 视为继承链中每个渲染模板的上下文列表。

### 新的管理功能

Django 1.1  在  Django  的管理界面中增加了几个很棒的新功能：

#### 在更改列表上的可编辑字段

现在你可以通过新的 [list\_editable](/zh-hans/6.1/ref/contrib/admin/#admin-list-editable) 管理选项在管理员列表视图上使字段可编辑。这些字段将显示为表单小部件在列表页面上，并可以批量编辑和保存。

#### 管理界面的"动作"

现在你可以定义可以批量对一组模型执行某些操作的 [管理员操作](/zh-hans/6.1/ref/contrib/admin/actions/)。用户将能够在更改列表页面上选择对象，然后将这些批量操作应用于所有选定的对象。

Django 默认提供了一个预定义的管理动作，可以一次性删除一组对象。

### 条件视图处理

Django 现在对使用标准的 `ETag` 和 `Last-Modified` HTTP 头部的 [条件视图处理](/zh-hans/6.1/topics/conditional-view-processing/) 提供了更好的支持。这意味着你现在可以通过测试成本较低的条件来轻松地中断视图处理。对于许多视图来说，这可以大大提高速度并减少带宽消耗。

### URL 命名空间

Django 1.1 引入了 URL "命名空间"，提升了 [命名的 URL 模式](/zh-hans/6.1/topics/http/urls/#naming-url-patterns)。

简而言之，这个功能允许相同的应用程序中的同一组 URL 在 Django 的 URLConf 中多次包含，使用不同（且可能嵌套）的命名前缀进行反向解析。换句话说，像 Django 的管理界面这样的可重用应用程序可以多次注册而不会出现 URL 冲突。

详细信息，请参阅 [关于定义 URL 命名空间的文档](/zh-hans/6.1/topics/http/urls/#topics-http-defining-url-namespaces)。

### GeoDjango

在 Django 1.1 中，[GeoDjango](/zh-hans/6.1/ref/contrib/gis/) （即 `django.contrib.gis`）引入了一些新功能：

- 支持将 [SpatiaLite](https://www.gaia-gis.it/gaia-sins/) （SQLite 的空间数据库）作为空间后端。
- 地理聚合函数（`Collect`、`Extent`、`MakeLine`、`Union`）和 `F` 表达式。
- 新的 `GeoQuerySet` 方法：`collect`、`geojson` 和 `snap_to_grid`。
- `GEOSGeometry` 对象的新列表接口方法。

要了解更多详细信息，请参阅 GeoDjango 文档。

### 其他改进

自 Django 1.0 以来引入的其他新功能和更改包括：

- [CSRF 保护中间件](/zh-hans/6.1/ref/csrf/) 现在分成了两个类 -- `CsrfViewMiddleware` 用于检查传入请求，而 `CsrfResponseMiddleware` 用于处理传出响应。合并的 `CsrfMiddleware` 类（同时处理两者）仍然存在以保持向后兼容性，但现在建议使用拆分的类来允许精细控制 CSRF 处理发生的时间和地点。
- `reverse()` 和使用它的代码（例如，`{% url %}` 模板标签）现在可以在 Django 的管理站点中使用，前提是通过 `include(admin.site.urls)` 设置了管理站点的 URL（仍然可以通过将管理请求发送到 `admin.site.root` 视图来工作，但以这种方式配置时，管理站点中的 URL 将无法“反向生成”）。
- Django URLconf 模块中的 `include()` 函数现在可以接受 URL 模式的序列（由 `patterns()` 生成）以及模块名称。
- Django 表单的实例（参见 [表单概述](/zh-hans/6.1/topics/forms/)）现在具有两个额外的方法，`hidden_fields()` 和 `visible_fields()`，分别返回表单中隐藏字段（即 `<input type="hidden">`）和可见字段的列表。
- `redirect_to` 通用视图现在接受一个额外的关键字参数 `permanent`。如果 `permanent` 为 `True`，视图将发出 HTTP 永久重定向（状态码 301）。如果为 `False`，视图将发出 HTTP 临时重定向（状态码 302）。
- 已经为 `DateField` 和 `DateTimeField` 添加了一个新的数据库查找类型 -- `week_day`。这种查找类型接受一个介于 1（星期日）和 7（星期六）之间的数字，并返回字段值匹配该周的对象。有关详细信息，请参阅 [查找类型的完整列表](/zh-hans/6.1/ref/models/querysets/#field-lookups)。
- Django 模板语言中的 `{% for %}` 标签现在接受一个可选的 `{% empty %}` 子句，当 `{% for %}` 被要求循环遍历一个空序列时，可以显示该子句。有关示例，请参阅 [内置模板标签列表](/zh-hans/6.1/ref/templates/builtins/)。
- [`dumpdata`](/zh-hans/6.1/ref/django-admin/#django-admin-dumpdata) 管理命令现在接受单个模型名称作为参数，允许你仅导出特定模型的数据。
- 新增了一个 [`safeseq`](/zh-hans/6.1/ref/templates/builtins/#std-templatefilter-safeseq) 模板过滤器，与 [`safe`](/zh-hans/6.1/ref/templates/builtins/#std-templatefilter-safe) 类似，但用于列表，将列表中的每个项目标记为安全。
- [缓存后端](/zh-hans/6.1/topics/cache/) 现在支持 `incr()` 和 `decr()` 命令，用于增加和减少缓存键的值。在支持原子增加/减少的缓存后端上，尤其是 memcached 后端，这些操作将是原子的，而且非常快。
- Django 现在可以通过一个新的身份验证后端轻松地将身份验证委托给 Web 服务器，该后端支持用于此目的的标准 `REMOTE_USER` 环境变量。请参阅 [如何将身份验证委托给 Web 服务器](/zh-hans/6.1/howto/auth-remote-user/) 以获取详细信息。
- 新增了一个 [`django.shortcuts.redirect()`](/zh-hans/6.1/topics/http/shortcuts/#django.shortcuts.redirect) 函数，使得根据对象、视图名称或 URL 发出重定向变得更加容易。
- `postgresql_psycopg2` 后端现在支持 [本地 PostgreSQL 自动提交](/zh-hans/6.1/ref/databases/#postgresql-notes)。这是一个高级的、特定于 PostgreSQL 的功能，可以使某些读密集型应用程序变得更加快速。

## 接下来是什么?

我们会休息一下，然后开始 Django 1.2 的工作 —— 休息是为了走更远！如果你想要帮助，关于 Django 开发的讨论，包括朝向 1.2 版本的进展，每天都在 [django-developers](/zh-hans/6.1/internals/mailing-lists/#django-developers-mailing-list) 邮件列表和 `#django-dev` IRC 频道上进行。欢迎加入讨论！

Django 的在线文档还包括如何为 Django 做出贡献的指南：

- [如何为 Django 做贡献](/zh-hans/6.1/internals/contributing/)

对于任何级别的贡献，无论是开发代码、撰写文档还是简单地对问题进行筛选并帮助测试提议的错误修复，我们都非常欢迎和感激。

就是这样。
