Django 1.4 发行说明 — Django 文档

来自菜鸟教程
Django/docs/2.2.x/releases/1.4
跳转至:导航、​搜索

Django 1.4 发行说明

2012 年 3 月 23 日

欢迎使用 Django 1.4!

这些发行说明涵盖了 新功能 ,以及从 Django 1.3 或更旧版本升级时您需要注意的一些 向后不兼容更改 。 我们还删除了一些功能,在 我们的弃用计划 中有详细说明,我们已经 开始了一些功能的弃用过程

概述

Django 1.4 中最大的新特性是处理日期/时间时对时区的 支持 。 启用后,此 Django 将以 UTC 存储日期/时间,在内部使用时区感知对象,并将它们转换为用户的本地时区以进行显示。

如果您要将现有项目升级到 Django 1.4,切换到时区感知模式可能需要小心:新模式不允许一些过去被接受的相当草率的行为。 我们鼓励任何正在升级的人查看 时区迁移指南时区常见问题 以获得有用的指示。

Django 1.4 中其他值得注意的新特性包括:

在可能的情况下,我们尝试按照 我们的 API 稳定性策略 策略以向后兼容的方式引入新功能。 然而,与之前的版本一样,Django 1.4 附带了一些小的 向后不兼容的更改 ; 从以前版本的 Django 升级的人应该仔细阅读该列表。


Python兼容性

Django 1.4 已放弃对 Python 2.4 的支持。 Python 2.5 现在是所需的最低 Python 版本。 Django 在 Python 2.5、2.6 和 2.7 上得到测试和支持。

此更改应仅影响少数 Django 用户,因为当今大多数操作系统供应商都将 Python 2.5 或更高版本作为其默认版本提供。 但是,如果您仍在使用 Python 2.4,则需要坚持使用 Django 1.3,直到您可以升级。 根据 我们的支持政策 ,Django 1.3 将继续获得安全支持,直到 Django 1.5 发布。

Django 目前不支持 Python 3.x。 在 Django 1.4 发布之前的某个时候,我们计划发布一份文档,概述弃用 Python 2.x 并迁移到 Python 3.x 的完整时间表。


Django 1.4 中的新功能

支持时区

在以前的版本中,Django 使用“天真的”日期/时间(即没有关联时区的日期/时间),让每个开发人员来解释给定的日期/时间“真正意味着”什么。 这可能会导致各种与时区相关的微妙错误。

在 Django 1.4 中,您现在可以将 Django 切换到更正确的时区感知模式。 在这种模式下,Django 将日期和时间信息以 UTC 格式存储在数据库中,在内部使用时区感知日期时间对象并将它们转换为模板和表单中最终用户的时区。 使用此功能的原因包括:

  • 为世界各地的用户定制日期和时间显示。
  • 以 UTC 格式存储日期时间以实现数据库可移植性和互操作性。 (此参数不适用于 PostgreSQL,因为它已经在 Django 1.3 中存储了带有时区信息的时间戳。)
  • 避免围绕 DST 转换的数据损坏问题。

在使用 :djadmin:`startproject` 创建的新项目中默认启用时区支持。 如果您想在现有项目中使用此功能,请阅读 迁移指南 。 如果您遇到问题,这里有一个有用的 FAQ


支持浏览器内测试框架

Django 1.4 支持与浏览器内测试框架的集成,如 Selenium。 新的 django.test.LiveServerTestCase 基类可让您更全面地测试站点前端和后端之间的交互。 有关更多详细信息和具体示例,请参阅 文档


更新了默认项目布局和 manage.py

Django 1.4 附带更新的默认项目布局和 :djadmin:`startproject` 管理命令的 manage.py 文件。 这些修复了之前 manage.py 处理 Python 导入路径的一些问题,这些问题导致双重导入、从开发到部署的麻烦以及其他难以调试的路径问题。

之前的 manage.py 调用了现在已弃用的函数,因此升级到 Django 1.4 的项目应该更新它们的 manage.py。 (旧式 manage.py 将继续像以前一样工作,直到 Django 1.6。 在 1.5 中,它将引发 DeprecationWarning)。

新推荐的 manage.py 文件应如下所示:

#!/usr/bin/env python
import os, sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

模板:Project name 应替换为实际项目的 Python 包名。

如果使用项目名称前缀(例如 myproject.settingsROOT_URLCONF = "myproject.urls"等),新的manage.py需要往上移一个目录,所以它在工程包外而不是与[相邻] X152X] 和 urls.py

例如,具有以下布局:

manage.py
mysite/
    __init__.py
    settings.py
    urls.py
    myapp/
        __init__.py
        models.py

您可以导入 mysite.settingsmysite.urlsmysite.myapp,但不能导入 settingsurlsmyapp 作为顶部级模块。

任何作为顶级模块导入的东西都可以放置在新的 manage.py 旁边。 例如,要将“myapp”与项目模块分离并将其作为 myapp 导入,请将其放在 mysite/ 目录之外:

manage.py
myapp/
    __init__.py
    models.py
mysite/
    __init__.py
    settings.py
    urls.py

如果相同的代码导入不一致(有些地方有项目前缀,有些地方没有),切换到新的manage.py时需要清理导入。


自定义项目和应用程序模板

:djadmin:`startapp`:djadmin:`startproject` 管理命令现在有一个 --template 选项,用于指定自定义应用程序或项目的路径或 URL模板。

例如,当您运行以下命令时,Django 将使用 /path/to/my_project_template 目录:

django-admin.py startproject --template=/path/to/my_project_template myproject

您现在还可以提供目标目录作为 :djadmin:`startapp`:djadmin:`startproject` 的第二个参数:

django-admin.py startapp myapp /path/to/new/app
django-admin.py startproject myproject /path/to/new/project

有关更多信息,请参阅 :djadmin:`startapp`:djadmin:`startproject` 文档。


改进的 WSGI 支持

:djadmin:`startproject` 管理命令现在在初始项目布局中添加了一个 wsgi.py 模块,其中包含一个简单的 WSGI 应用程序,可用于 部署 WSGI 应用服务器[ X208X]。

:djadmin:`内置开发服务器 ` 现在支持使用外部定义的 WSGI 可调用,这使得运行成为可能runserver具有用于部署的相同 WSGI 配置。 新的 :setting:`WSGI_APPLICATION` 设置允许您配置哪个 WSGI 可调用 :djadmin:`runserver` 使用。

runfcgi 管理命令也在内部封装了通过 :setting:`WSGI_APPLICATION` 配置的 WSGI callable。)


SELECT FOR UPDATE 支持

Django 1.4 包含一个 QuerySet.select_for_update() 方法,它生成一个 SELECT ... FOR UPDATE SQL 查询。 这将锁定行直到事务结束,这意味着其他事务无法修改或删除与 FOR UPDATE 查询匹配的行。

有关更多详细信息,请参阅 select_for_update() 的文档。


ORM中的Model.objects.bulk_create

此方法可让您更有效地创建多个对象。 如果您有许多对象,它可能会显着提高性能。

Django 在内部使用它,这意味着某些操作(例如测试套件的数据库设置)已经看到了性能优势。

有关更多信息,请参阅 bulk_create() 文档。


改进的密码散列

Django 的身份验证系统 (django.contrib.auth) 使用单向算法存储密码。 Django 1.3 使用 SHA1 算法,但提高处理器速度和理论攻击表明 SHA1 并不像我们希望的那么安全。 因此,Django 1.4 引入了一个新的密码存储系统:默认情况下,Django 现在使用 PBKDF2 算法(由 NIST 推荐)。 您还可以轻松选择不同的算法(包括流行的 bcrypt 算法)。 更多详细信息,请参见 Django 如何存储密码


HTML5 文档类型

我们已将管理和其他捆绑模板切换为使用 HTML5 文档类型。 虽然 Django 会小心地保持与旧浏览器的兼容性,但此更改意味着您可以在管理页面中使用您需要的任何 HTML5 功能,而不必失去 HTML 有效性或覆盖提供的模板来更改文档类型。


在管理界面中列出过滤器

在 Django 1.4 之前,admin 应用程序允许您通过指定字段查找来指定更改列表过滤器,但它不允许您创建自定义过滤器。 这已通过一个简单的 API(以前在内部使用,称为“FilterSpec”)得到纠正。 有关更多详细信息,请参阅 list_filter 的文档。


管理界面中的多重排序

管理员更改列表现在支持对多列进行排序。 它尊重 ordering 属性的所有元素,并且通过单击标题对多列进行排序旨在模仿桌面 GUI 的行为。 我们还添加了一个 get_ordering() 方法来动态指定排序(即,取决于请求)。


新的 ModelAdmin 方法

我们向 ModelAdmin 添加了一个 save_related() 方法,以简化在管理中如何保存相关对象的自定义。

另外两个新的 ModelAdmin 方法 get_list_display()get_list_display_links() 支持动态自定义显示在管理更改列表上的字段和链接。


管理员内联尊重用户权限

管理员内联现在只允许用户有权执行的那些操作。 对于与自动创建的中间模型(它没有自己的权限)的 ManyToMany 关系,相关模型的更改权限决定用户是否有权添加、更改或删除关系。


加密签名工具

Django 1.4 添加了用于对值进行签名的低级 API 和用于设置和读取签名 cookie 的高级 API,这是在 Web 应用程序中签名的最常见用途之一。

有关更多信息,请参阅 加密签名 文档。


新建表单向导

之前来自 django.contrib.formtoolsFormWizard 已被替换为基于 Django 1.3 中引入的基于类的视图的新实现。 它具有可插入的存储 API,并且不需要向导为之前的每个步骤传递隐藏字段。

Django 1.4 附带了一个基于会话的存储后端和一个基于 cookie 的存储后端。 后者使用 Django 1.4 中引入的 加密签名 工具将向导的状态存储在用户的 cookie 中。


reverse_lazy

添加了 reverse() 的惰性评估版本,以允许在加载项目的 URLconf 之前使用 URL 反转。


翻译 URL 模式

Django 现在可以在使用新的 i18n_patterns() 辅助函数时在 URLpattern 中查找语言前缀。 现在还可以使用 ugettext_lazy() 定义可翻译的 URL 模式。 有关语言前缀和如何国际化 URL 模式的更多信息,请参阅 国际化:在 URL 模式中


{% trans %} 和 {% blocktrans %} 的上下文翻译支持

Django 1.3 中通过 pgettext 函数引入的 上下文翻译 支持已扩展到 :ttag:`trans`:ttag:`blocktrans` 模板标签使用新的 context 关键字。


可定制的 SingleObjectMixin URLConf kwargs

两个新属性 pk_url_kwargslug_url_kwarg 已添加到 SingleObjectMixin 以启用用于单个对象通用视图的 URLconf 关键字参数的自定义。


作业模板标签

一个新的 assignment_tag 辅助函数被添加到 template.Library 以简化将数据存储在指定上下文变量中的模板标签的创建。


*args 和 **kwargs 支持模板标签辅助函数

simple_taginclusion_tag 和新引入的 assignment_tag 模板辅助函数现在可以接受任意数量的位置或关键字参数。 例如:

@register.simple_tag
def my_tag(a, b, *args, **kwargs):
    warning = kwargs['warning']
    profile = kwargs['profile']
    ...
    return ...

然后,在模板中,可以将任意数量的参数传递给模板标签。 例如:

{% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}

TEMPLATE_DEBUG 模式下没有异常包装

在以前的 Django 版本中,每当 TEMPLATE_DEBUG 设置为 True 时,模板渲染期间引发的任何异常(甚至与模板语法无关的异常)都被包装在 TemplateSyntaxError 中并重新引发. 这样做是为了在调试 500 页面中提供详细的模板源位置信息。

在 Django 1.4 中,不再包装异常。 相反,原始异常使用源信息进行注释。 这意味着无论 TEMPLATE_DEBUG 的值如何,从模板渲染中捕获异常现在都是一致的,并且无需捕获和解包 TemplateSyntaxError 以捕获其他错误。


truncatechars 模板过滤器

这个新过滤器将字符串截断为不超过指定的字符数。 截断的字符串以可翻译的省略号序列 (“...”) 结尾。 有关更多详细信息,请参阅 :tfilter:`truncatechars` 的文档。


static 模板标签

staticfiles contrib 应用程序有一个新的 static 模板标签,用于引用使用 :setting:`STATICFILES_STORAGE` 存储后端保存的文件。 它使用存储后端的 url 方法,因此支持高级功能,例如 从云服务 提供文件。


CachedStaticFilesStorage 存储后端

staticfiles contrib 应用程序现在有一个 django.contrib.staticfiles.storage.CachedStaticFilesStorage 后端,通过附加 MD5 哈希缓存它保存的文件(运行 :djadmin:`collectstatic` 管理命令时)文件内容到文件名。 例如,文件 css/styles.css 也将保存为 css/styles.55e7cbb9ba48.css


简单的点击劫持保护

我们添加了一个中间件,以使用 X-Frame-Options 标头提供针对 clickjacking 的轻松保护。 出于向后兼容性的原因,默认情况下未启用它,但您几乎肯定希望 启用它 以帮助为支持标头的浏览器插入该安全漏洞。


CSRF 改进

我们对 CSRF 功能进行了各种改进,包括 ensure_csrf_cookie() 装饰器,它可以帮助处理 AJAX 密集型网站; 保护 PUT 和 DELETE 请求; 以及 :setting:`CSRF_COOKIE_SECURE`:setting:`CSRF_COOKIE_PATH` 设置,可以提高 CSRF 保护的安全性和实用性。 有关更多信息,请参阅 CSRF 文档


错误报告过滤

我们添加了两个函数装饰器,sensitive_variables()sensitive_post_parameters(),以允许指定可能包含敏感信息并应从错误报告中过滤掉的局部变量和 POST 参数。

现在,所有 POST 参数都被系统地从某些视图的错误报告中过滤掉(django.contrib 中的 loginpassword_reset_confirmpassword_changeadd_view。 auth.views,以及管理应用中的user_change_password),以防止用户密码等敏感信息泄露。

您可以通过编写 自定义过滤器 来覆盖或自定义默认过滤。 有关更多信息,请参阅有关 过滤错误报告 的文档。


扩展的 IPv6 支持

Django 1.4 现在可以使用新的 GenericIPAddressField 模型字段、GenericIPAddressField 表单字段和验证器 validate_ipv46_address 和 _validate_ip2v7 更好地处理 IPv6 地址


测试中的 HTML 比较

django.test 中的基类现在有一些帮助程序来比较 HTML,而不会因空格、参数引用/排序和自闭合标签的关闭不相关的差异而绊倒。 您可以直接将 HTML 与新的 assertHTMLEqual()assertHTMLNotEqual() 断言进行比较,或者将 html=True 标志与 assertContains() 一起使用和 assertNotContains() 来测试客户端的响应是否包含给定的 HTML 片段。 有关更多信息,请参阅 断言文档


两个新的日期格式字符串

添加了两种新的 :tfilter:`date` 格式,用于模板过滤器、模板标签和 格式本地化

  • e – 给定日期时间对象的时区名称
  • o – ISO 8601 年号

如果格式字符串中包含 eo,请确保更新您的 自定义格式文件 。 例如,以前的西班牙语本地化格式仅转义 d 格式字符:

DATE_FORMAT = r'j \de F \de Y'

但现在它也需要转义 eo

DATE_FORMAT = r'j \d\e F \d\e Y'

有关更多信息,请参阅 :tfilter:`date` 文档。


小功能

Django 1.4 还包括几个值得注意的小改进:

  • 技术 500 页中更有用的堆栈跟踪。 堆栈跟踪中引用 Django 框架代码的帧变暗,而应用程序代码中的帧略微强调。 此更改使扫描堆栈跟踪以查找应用程序代码中的问题变得更加容易。
  • PostgreSQL 中的表空间支持
  • simple_tag() 的可自定义名称。
  • 在文档中,有一个有用的 安全概述 页面。
  • django.contrib.auth.models.check_password 功能已移至 django.contrib.auth.hashers 模块。 从旧位置导入它仍然有效,但您应该更新您的导入。
  • :djadmin:`collectstatic` 管理命令现在有一个 --clear 选项,可以在复制或链接静态文件之前删除目的地的所有文件。
  • 现在可以在将 MySQL 与 InnoDB 数据库引擎一起使用时加载包含前向引用的装置。
  • 新的 403 响应处理程序已添加为 'django.views.defaults.permission_denied'。 您可以通过设置 django.conf.urls.handler403 的值来设置自己的处理程序。 有关详细信息,请参阅有关 403(HTTP 禁止)视图 的文档。
  • :djadmin:`makemessages` 命令使用新的更准确的词法分析器 JsLex,从 JavaScript 文件中提取可翻译的字符串。
  • :ttag:`trans` 模板标签现在采用可选的 as 参数,以便能够在不显示的情况下检索翻译字符串,而是设置模板上下文变量。

  • :ttag:`if` 模板标签现在支持 {% elif %} 子句。

  • 如果您的 Django 应用程序位于代理之后,您可能会发现新的 :setting:`SECURE_PROXY_SSL_HEADER` 设置很有用。 它解决了您的代理“吃掉”请求通过 HTTPS 传入这一事实的问题。 但仅当您知道自己在做什么时才使用此设置。

  • :setting:`DEBUG`True 时提供的 HTTP 500 状态代码内部错误页面的新纯文本版本现在会在 Django 检测到请求时发送到客户端起源于 JavaScript 代码。 (is_ajax() 用于此。)

    与其对应的 HTML 一样,它包含有关应用程序状态的不同信息片段的集合。

    在调试与客户端 JavaScript 的交互时,这应该更容易阅读。

  • 添加了 makemessages --no-location 选项。

  • locmem 缓存后端更改为使用 pickle.HIGHEST_PROTOCOL 以更好地与其他缓存后端兼容。

  • 在 ORM 中添加了对生成包含 DISTINCT ONSELECT 查询的支持。

    distinct() QuerySet 方法现在接受可选的模型字段名称列表。 如果指定,则 DISTINCT 语句仅限于这些字段。 这仅在 PostgreSQL 中受支持。

    有关更多详细信息,请参阅 distinct() 的文档。

  • 如果您在 urls.py 中包含名称为 'admin_password_reset' 的 URL,管理员登录页面将添加密码重置链接,因此现在插入内置密码重置机制并使其可用更轻松。 具体参见【X17X】增加密码重置功能【X52X】。

  • MySQL 数据库后端现在可以利用 MySQL 5.0.3 或更高版本通过 InnoDB 存储引擎实现的保存点功能。

  • 现在可以将初始值传递给作为模型表单集和内联模型表单集一部分的模型表单,分别从工厂函数 modelformset_factoryinlineformset_factory 返回,就像使用常规表单集一样。 但是,初始值仅适用于额外的形式,即 那些未绑定到现有模型实例的。

  • 站点地图框架现在可以使用新的 Sitemap.protocol 类属性处理 HTTPS 链接。

  • 一个新的 django.test.SimpleTestCase 子类 unittest.TestCasedjango.test.TestCase 和公司更轻。 它在不需要访问数据库的测试中很有用。 请参阅 Django 单元测试类的层次结构


1.4 中向后不兼容的变化

需要 SECRET_KEY 设置

使用空的或已知的 :setting:`SECRET_KEY` 运行 Django 会禁用 Django 的许多安全保护,并可能导致远程代码执行漏洞。 没有 :setting:`SECRET_KEY`,任何 Django 站点都不应该运行。

在 Django 1.4 中,以空 :setting:`SECRET_KEY` 启动 Django 将引发 DeprecationWarning。 在 Django 1.5 中,它将引发异常并且 Django 将拒绝启动。 由于在没有 :setting:`SECRET_KEY` 的情况下运行 Django 的后果的严重性,这比通常的弃用路径略有加速。


django.contrib.admin

随附的管理应用程序 django.contrib.admin 长期以来一直带有一组默认的静态文件,例如 JavaScript、图像和样式表。 Django 1.3 添加了一个新的 contrib 应用程序 django.contrib.staticfiles 以通用方式处理此类文件,并为应用程序中包含的静态文件定义了约定。

从 Django 1.4 开始,管理员的静态文件也遵循这个约定,使文件更容易部署。 在以前的 Django 版本中,定义 ADMIN_MEDIA_PREFIX 设置指向管理员静态文件在 Web 服务器上的 URL 也是很常见的。 此设置现在已被弃用,取而代之的是更通用的设置 :setting:`STATIC_URL`。 Django 现在期望在 URL <STATIC_URL>/admin/ 下找到管理静态文件。

如果您之前使用过 ADMIN_MEDIA_PREFIX 的 URL 路径(例如 /media/) 只需确保 :setting:`STATIC_URL`:setting:`STATIC_ROOT` 已配置并且您的 Web 服务器正确地提供这些文件。 开发服务器继续像以前一样提供管理文件。 阅读 静态文件 howto 了解更多详情。

如果您的 ADMIN_MEDIA_PREFIX 设置为特定域(例如 http://media.example.com/admin/),请确保还将您的 :setting:`STATIC_URL` 设置设置为正确的 URL - 例如,http://media.example.com/

警告

如果您隐式依赖 Django 源代码中管理静态文件的路径,则需要更新该路径。 文件从 django/contrib/admin/media/ 移动到 django/contrib/admin/static/admin/


管理员支持的浏览器

Django 还没有关于管理应用程序支持哪些浏览器的明确政策。 我们的新政策使现有做法正式化:YUI 的 A 级 浏览器应提供功能齐全的管理体验,但 Internet Explorer 6 除外,该浏览器不再受支持。

10 多年前发布的 IE6 对现代 Web 开发施加了许多限制。 该政策的实际含义是,贡献者可以自由地改进管理,而无需考虑这些限制。

显然,这项新政策 对您使用 Django 开发的网站没有影响 。 它仅适用于 Django 管理员。 随意开发与任何浏览器兼容的应用程序。


删除了管理员图标

作为提高管理员更改列表排序界面和 horizontalvertical“过滤器”小部件的性能和可用性的努力的一部分,一些图标文件被删除并分为两个精灵文件。

具体:selector-add.gifselector-addall.gifselector-remove.gifselector-removeall.gifselector_stacked-add.gifselector_stacked-remove.gif组合成[ X105X]; arrow-up.gifarrow-down.gif合并为sorting-icons.gif

如果您使用这些图标来自定义管理,那么您需要将它们替换为您自己的图标或从以前的版本中获取文件。


管理表单中的 CSS 类名

为了避免与其他常见的 CSS 类名(例如 “button”),我们为所有从主管理表单、堆叠内联表单和表格内联单元格中的表单字段名称自动生成的 CSS 类名称添加了前缀(“field-”)。 如果您以前使用普通字段名称作为自定义样式或 JavaScript 转换的选择器,则需要在自定义样式表或 JavaScript 文件中考虑该前缀。


与旧签名数据的兼容性

Django 1.3 更改了 Django 中许多地方使用的加密签名机制。 虽然 Django 1.3 保留了接受先前方法生成的哈希的回退,但这些回退在 Django 1.4 中被删除。

因此,如果您直接从 1.2 或更早版本升级到 Django 1.4,您可能会丢失/无效某些使用旧方法加密签名的数据。 为避免这种情况,请先使用 Django 1.3 一段时间,让签名数据自然过期。 受影响的部分详述如下,1) 忽略此建议的后果和 2) 运行 Django 1.3 所需的时间以使数据过期或变得无关紧要。

与表单相关的哈希:它们的生命周期要短得多,并且仅与用户可能填写由升级前 Django 实例生成的表单并尝试将其提交给升级后的 Django 实例的短窗口相关:

  • contrib.comments 表单安全哈希
    • 结果:用户将看到验证错误“安全哈希失败”。
    • 时间段:您希望用户填写评论表单的时间。
  • FormWizard 安全哈希
    • 后果:用户将看到有关表单已过期的错误,并将被发送回向导的第一页,从而丢失迄今为止输入的数据。
    • 时间段:您希望用户填写受影响表单所花费的时间。
  • CSRF检查
    • 注意:这实际上是 Django 1.1 的回退,而不是 Django 1.2,它仅适用于从 1.1 升级的情况。
    • 后果:用户将在任何受 CSRF 保护的 POST 表单中看到 403 错误。
    • 时间段:您希望用户填写此类表格所需的时间。
  • contrib.auth 用户密码哈希升级序列
    • 后果:在 1.4 中写入数据库时,每个用户的密码都会更新为更强的密码哈希。 这意味着如果您升级到 1.4,然后需要降级到 1.3,1.3 版将无法读取更新后的密码。
    • 补救措施:当您最初升级到 1.4 时,将 :setting:`PASSWORD_HASHERS` 设置为使用您的原始密码散列。 在您确认您的应用程序与 Django 1.4 配合良好并且您不必回滚到 1.3 后,启用新的密码哈希。


django.contrib.flatpages

从 1.4 开始,FlatpageFallbackMiddleware 仅添加尾部斜杠并在结果 URL 引用现有平面页面时重定向。 例如,在以前的版本中请求 /notaflatpageoravalidurl 将重定向到 /notaflatpageoravalidurl/,随后会引发 404。 现在请求 /notaflatpageoravalidurl 将立即引发 404。

此外,flatpages 返回的重定向现在是永久性的(带有 301 状态代码),以匹配 CommonMiddleware 的行为。


datetime和time的序列化

由于时区支持,并根据 ECMA-262 规范,我们对 JSON 序列化程序进行了更改:

  • 它包括感知日期时间对象的时区。 它引发了感知时间对象的异常。
  • 它包括日期时间和时间对象的毫秒数。 仍然有一些精度损失,因为 Python 存储微秒(6 位)而 JSON 仅支持毫秒(3 位)。 但是,这比完全丢弃微秒要好。

我们将 XML 序列化程序更改为对日期时间使用 ISO8601 格式。 字母 T 用于将日期部分与时间部分分开,而不是空格。 时区信息包含在 [+-]HH:MM 格式中。

尽管序列化器现在在创建夹具时使用这些新格式,但它们仍然可以加载使用旧格式的夹具。


SQLite 的 supports_timezone 更改为 False

SQLite 的数据库特性 supports_timezone 曾经是 True。 事实上,如果你保存了一个有意识的日期时间对象,SQLite 会存储一个包含 UTC 偏移量的字符串。 但是,从数据库加载值时会忽略此偏移量,这可能会损坏数据。

在时区支持的上下文中,此标志已更改为 False,并且日期时间现在在 SQLite 中存储时没有时区信息。 当 :setting:`USE_TZ`False 时,如果您尝试保存一个已知的日期时间对象,Django 会引发异常。


MySQLdb-特定异常

历史上,当查询触发异常时,MySQL 后端会引发 MySQLdb.OperationalError。 我们已经修复了这个错误,现在我们提出 django.db.DatabaseError。 如果您正在测试 MySQLdb.OperationalError,则需要更新 except 子句。


数据库连接的线程局部性

DatabaseWrapper 对象(即 django.db.connectiondjango.db.connections["some_alias"]) 引用的连接对象曾经是线程本地的。 它们现在是全局对象,以便在多个线程之间潜在地共享。 虽然各个连接对象现在是全局的,但引用这些对象的 django.db.connections 字典仍然是线程本地的。 因此,如果您只使用 ORM 或 DatabaseWrapper.cursor(),则行为仍与以前相同。 但是请注意,django.db.connection 不再直接引用默认的 DatabaseWrapper 对象,现在是访问该对象属性的代理。 如果您需要访问实际的 DatabaseWrapper 对象,请改用 django.db.connections[DEFAULT_DB_ALIAS]

作为此更改的一部分,所有底层 SQLite 连接现在都启用了潜在的线程共享(通过将 check_same_thread=False 属性传递给 pysqlite)。 然而,DatabaseWrapper 通过默认禁用线程共享来保留以前的行为,因此这不会影响任何纯粹依赖 ORM 或 DatabaseWrapper.cursor() 的现有代码。

最后,虽然现在可以在线程之间传递连接,但 Django 没有做任何努力来同步对底层后端的访问。 并发行为由底层后端实现定义。 查看他们的文档以获取详细信息。


COMMENTS_BANNED_USERS_GROUP 设置

Django 的评论历来支持排除特殊用户组的评论,但我们从未正确记录该功能,也没有在应用程序的其他部分(例如模板标签)中强制排除。 为了解决这个问题,我们从提要类中删除了代码。

如果您依赖该功能并希望恢复旧行为,请使用自定义评论模型管理器来排除用户组,如下所示:

from django.conf import settings
from django.contrib.comments.managers import CommentManager

class BanningCommentManager(CommentManager):
    def get_query_set(self):
        qs = super().get_query_set()
        if getattr(settings, 'COMMENTS_BANNED_USERS_GROUP', None):
            where = ['user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)']
            params = [settings.COMMENTS_BANNED_USERS_GROUP]
            qs = qs.extra(where=where, params=params)
        return qs

将此模型管理器保存在您的自定义评论应用程序中(例如,在 my_comments_app/managers.py 中)并将其添加到您的自定义评论应用程序模型中:

from django.db import models
from django.contrib.comments.models import Comment

from my_comments_app.managers import BanningCommentManager

class CommentWithTitle(Comment):
    title = models.CharField(max_length=300)

    objects = BanningCommentManager()

IGNORABLE_404_STARTS 和 IGNORABLE_404_ENDS 设置

在 Django 1.3 之前,可以通过向 IGNORABLE_404_STARTS 添加前缀和向 IGNORABLE_404_ENDS 添加后缀来从 Django 的 404 错误报告 中排除一些 URL。

在 Django 1.4 中,这两个设置被 :setting:`IGNORABLE_404_URLS` 取代,这是一个已编译的正则表达式列表。 Django 不会针对与其中任何一个匹配的 URL 发送 404 错误的电子邮件。

此外,之前的设置有一些相当随意的默认值:

IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf')
IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi',
                      'favicon.ico', '.php')

决定您的网站是否具有旧版 /cgi-bin/ 部分或 favicon.ico 不是 Django 的职责。 因此,:setting:`IGNORABLE_404_URLS`IGNORABLE_404_STARTSIGNORABLE_404_ENDS 的默认值现在都为空。

如果您自定义了 IGNORABLE_404_STARTSIGNORABLE_404_ENDS,或者您想保留旧的默认值,您应该在您的设置文件中添加以下几行:

import re
IGNORABLE_404_URLS = (
    # for each <prefix> in IGNORABLE_404_STARTS
    re.compile(r'^<prefix>'),
    # for each <suffix> in IGNORABLE_404_ENDS
    re.compile(r'<suffix>$'),
)

不要忘记转义在正则表达式中具有特殊含义的字符,例如句点。


CSRF 保护扩展到 PUT 和 DELETE

以前,Django 的 CSRF 保护 仅提供针对 POST 请求的保护。 由于在 AJAX 应用程序中使用 PUT 和 DELETE 方法变得越来越普遍,我们现在保护所有未被 RFC 2616 定义为安全的方法——即,我们免除 GET、HEAD、OPTIONS 和TRACE,我们对其他所有内容实施保护。

如果您在 AJAX 应用程序中使用 PUT 或 DELETE 方法,请参阅 关于使用 AJAX 和 CSRF 的说明。


密码重置视图现在接受 subject_template_name

django.contrib.auth 中的 password_reset 视图现在接受 subject_template_name 参数,该参数作为关键字参数传递给密码保存表单。 如果您将此视图与自定义密码重置表单一起使用,则您需要确保表单的 save() 方法接受此关键字参数。


django.core.template_loaders

这是自 2005 年以来 django.template.loader 的别名,由于弃用的时间太长,我们已将其删除而没有发出警告。 如果您的代码仍然引用此内容,请改用 django.template.loader


django.db.models.fields.URLField.verify_exists

由于难以处理的性能和安全问题,此功能已被删除。 应删除任何现有的 verify_exists 用法。


django.core.files.storage.Storage.open

Storage 基类的 open 方法曾经采用一个模糊参数 mixin,它允许您动态更改返回文件对象的基类。 这已被删除。 在您依赖 mixin 参数的罕见情况下,您可以通过覆盖 open 方法轻松实现相同的效果,如下所示:

from django.core.files import File
from django.core.files.storage import FileSystemStorage

class Spam(File):
    """
    Spam, spam, spam, spam and spam.
    """
    def ham(self):
        return 'eggs'

class SpamStorage(FileSystemStorage):
    """
    A custom file storage backend.
    """
    def open(self, name, mode='rb'):
        return Spam(open(self.path(name), mode))

YAML 解串器现在使用 yaml.safe_load

yaml.load 能够构造任何 Python 对象,如果您处理来自不受信任来源的 YAML 文档,这可能会触发任意代码执行。 Django 的 YAML 反序列化器不需要此功能,其主要用途是加载由简单对象组成的装置。 尽管装置是受信任的数据,但 YAML 反序列化器现在使用 yaml.safe_load 来提高安全性。


会话 cookie 现在默认具有 httponly 标志

会话 cookie 现在默认包含 httponly 属性,以帮助减少潜在 XSS 攻击的影响。 由于此更改,会话 cookie 数据(包括 sessionid)在许多浏览器中不再可从 JavaScript 访问。 为了严格的向后兼容性,请在设置文件中使用 SESSION_COOKIE_HTTPONLY = False


:tfilter:`urlize` 过滤器不再转义每个 URL

当 URL 包含 %xx 序列时,其中 xx 是两个十六进制数字,:tfilter:`urlize` 现在假定 URL 已经被转义并且不适用URL 再次转义。 对于未加引号的形式包含 %xx 序列的 URL,这是错误的,但此类 URL 不太可能在野外发生,因为它们也会混淆浏览器。


assertTemplateUsed 和 assertTemplateNotUsed 作为上下文管理器

现在可以使用 assertTemplateUsed()assertTemplateNotUsed() 检查代码块中是否使用了模板。 它们可以用作上下文管理器:

with self.assertTemplateUsed('index.html'):
    render_to_string('index.html')
with self.assertTemplateNotUsed('base.html'):
    render_to_string('index.html')

有关更多信息,请参阅 断言文档


运行测试套件后的数据库连接

默认测试运行器在测试执行后不再恢复数据库连接。 这可以防止生产数据库暴露给仍在运行并尝试创建新连接的潜在线程。

如果您的代码依赖于在测试执行后创建的生产数据库的连接,那么您可以通过子类化 DjangoTestRunner 并覆盖其 teardown_databases() 方法来恢复以前的行为。


输出 :djadmin:`manage.py 帮助 `

:djadmin:`manage.py 帮助 ` 现在按应用程序对可用命令进行分组。 如果您依赖此命令的输出(例如,如果您对其进行了解析),那么您将需要更新您的代码。 要获取脚本中所有可用管理命令的列表,请使用 :djadmin:`manage.py 帮助 --commands ` 反而。


extends 模板标签

以前,:ttag:`extends` 标签使用了一个错误的解析参数的方法,这可能导致它错误地将参数视为字符串文字,而实际上它不是。 它现在使用 parser.compile_filter,就像其他标签一样。

标签的内部结构不是官方稳定 API 的一部分,但为了全面公开,ExtendsNode.__init__ 定义已更改,这可能会破坏使用此类的任何自定义标签。


加载一些不完整的装置不再有效

在 1.4 之前,当为字段设置 auto_now 或 auto_now_add 时,会为缺少特定日期或日期时间值的夹具对象插入默认值。 这是不应该起作用的,在 1.4 中加载这种不完整的装置会失败。 由于夹具是原始导入,因此它们应明确指定所有字段值,而不管模型上的字段选项如何。


开发服务器多线程

开发服务器现在默认是多线程的。 使用 runserver --nothreading 选项禁用开发服务器中线程的使用:

django-admin.py runserver --nothreading

设置安全模式时在降价中禁用的属性

在 Django 1.4 之前,无论过滤器的安全模式设置如何,属性都包含在任何降价输出中。 对于 Python-Markdown 库的版本 > 2.1,添加了 enable_attributes 选项。 当安全参数传递给降价过滤器时,safe_mode=Trueenable_attributes=False 选项都被设置。 如果使用低于 2.1 的 Python-Markdown 库版本,则会发出输出不安全的警告。


FormMixin get_initial 返回一个特定于实例的字典

在 Django 1.3 中,django.views.generic.edit.FormMixin 类的 get_initial 方法返回类 initial 字典。 这已被修复以返回此字典的副本,因此表单实例可以修改其初始数据而不会弄乱类变量。


1.4 中弃用的功能

调用 cache_page 装饰器的旧样式

一些调用 cache_page() 的传统方法已被弃用。 请参阅文档以了解使用此装饰器的正确方法。


支持早于 8.2 的 PostgreSQL 版本

Django 1.3 放弃了对早于 8.0 的 PostgreSQL 版本的支持,我们建议使用更新的版本,因为性能改进,更重要的是,8.0 和 8.1 的上游支持期即将结束(2010 年 11 月)。

Django 1.4 进一步采用了该策略,并将 8.2 设置为它正式支持的最低 PostgreSQL 版本。


现在总是记录请求异常

当我们在 1.3 中在 Django 中添加 日志支持 [X33X] 时,管理错误电子邮件支持被移到 django.utils.log.AdminEmailHandler 中,附加到 'django.request' 记录器。 为了保持错误邮件的既定行为,仅当 :setting:`DEBUG`False 时才调用 'django.request' 记录器。

为了增加请求错误记录的灵活性,现在调用 'django.request' 记录器,而不管 :setting:`DEBUG` 的值,新项目的默认设置文件现在包括附加到 django.utils.log.AdminEmailHandler 的单独过滤器,以防止 DEBUG 模式下的管理员错误电子邮件:

'filters': {
     'require_debug_false': {
         '()': 'django.utils.log.RequireDebugFalse'
     }
 },
 'handlers': {
     'mail_admins': {
         'level': 'ERROR',
         'filters': ['require_debug_false'],
         'class': 'django.utils.log.AdminEmailHandler'
     }
 },

如果您的项目是在此更改之前创建的,您的 :setting:`LOGGING` 设置将不包含此新过滤器。 为了保持向后兼容性,Django 将检测到您的 'mail_admins' 处理程序配置不包含 'filters' 部分,并将自动为您添加此过滤器并发出挂起弃用警告。 这将成为 Django 1.5 中的弃用警告,而在 Django 1.6 中,向后兼容性垫片将被完全删除。

'mail_admins' 处理程序下任何 'filters' 键的存在将禁用此向后兼容性垫片和弃用警告。


django.conf.urls.defaults

在 Django 1.3 之前,include()patterns()url() 函数,加上 handler404handler500 位于 django.conf.urls.defaults 模块。

在 Django 1.4 中,它们位于 django.conf.urls


django.contrib.databrowse

Databrowse 已经有一段时间没有看到积极的发展了,这也没有任何改变的迹象。 有人建议 GSOC 项目 将数据浏览的功能集成到管理中,但没有取得任何进展。 虽然 Databrowse 已被弃用,但仍可提供类似功能集的 django.contrib.admin 增强功能。

支持 Databrowse 的代码根据与 Django 本身相同的条款获得许可,因此它可以被个人或团体作为第三方项目采用。


django.core.management.setup_environ

此功能临时修改了 sys.path,以便在旧的平面 :djadmin:`startproject` 布局下可以导入父“项目”目录。 此功能现已弃用,因为新的 manage.py 和默认项目布局不再需要其路径变通方法。

此函数从未被记录或作为公共 API 的一部分,但被广泛推荐用于为用户脚本设置“Django 环境”。 这些用途应该通过设置 DJANGO_SETTINGS_MODULE 环境变量或使用 django.conf.settings.configure() 来代替。


django.core.management.execute_manager

这个函数以前被manage.py用来执行管理命令。 它与 django.core.management.execute_from_command_line 相同,除了它首先调用 setup_environ,现在已弃用。 因此,execute_manager 也被弃用; execute_from_command_line 可以代替。 这些函数都没有记录为公共 API 的一部分,但由于在现有 manage.py 文件中使用,需要弃用路径。


模板过滤器的 is_safe 和 needs_autoescape 属性

is_safeneeds_autoescape 两个标志定义了每个模板过滤器如何与 Django 的自动转义行为交互。 它们曾经是过滤器函数的属性:

@register.filter
def noop(value):
    return value
noop.is_safe = True

但是,这种技术在与装饰器结合使用时会出现一些问题,尤其是 @stringfilter。 现在,标志是 @register.filter 的关键字参数:

@register.filter(is_safe=True)
def noop(value):
    return value

有关更多信息,请参阅 过滤器和自动转义


INSTALLED_APPS中应用程序名称的通配符扩展

在 Django 1.3 之前,:setting:`INSTALLED_APPS` 接受应用程序名称中的通配符,例如 django.contrib.*。 扩展由基于文件系统的 from <package> import * 实现执行。 不幸的是,这不能可靠地完成。

这种行为从未被记录在案。 由于它不是 Pythonic 并且没有明显的用处,所以它在 Django 1.4 中被删除了。 如果您依赖它,则必须编辑设置文件以明确列出所有应用程序。


HttpRequest.raw_post_data 重命名为 HttpRequest.body

这个属性被命名为 HttpRequest.raw_post_data,但它实际上提供了 HTTP 请求的主体。 它已重命名为 HttpRequest.body,并且 HttpRequest.raw_post_data 已被弃用。


django.contrib.sitemaps 具有潜在性能影响的错误修复

在以前的版本中,站点地图类中使用的 Paginator 对象被缓存,这可能会导致站点地图过时。 我们已经移除了缓存,因此对站点地图的每个请求现在都会创建一个新的 Paginator 对象并调用 Sitemap 子类的 items() 方法。 根据您的 items() 方法正在执行的操作,这可能会对性能产生负面影响。 为了减轻性能影响,请考虑在您的 Sitemap 子类中使用 缓存框架


2.1 之前的 Python-Markdown 版本

早于 2.1 的 Python-Markdown 版本不支持禁用属性的选项。 作为安全问题,在加速弃用时间表下,1.5 中的标记 contrib 应用程序将不支持此库的早期版本。