Django 1.6发行说明

备注

献给马尔科姆·特雷丁尼克

2013年3月17日,Django项目和免费软件社区失去了一位非常亲爱的朋友和开发人员。

马尔科姆是德扬戈的长期贡献者,他是一个模范社区成员,一个聪明的头脑,一个朋友。他对Django和许多其他开源项目的贡献几乎无法列举。许多核心的Django团队的成员都对他们的第一个补丁进行了审查;他的指导丰富了我们。他的体贴、耐心和奉献精神将永远激励着我们。

本次发行的Django是为马尔科姆发行的。

--Django开发者

2013年11月6日

欢迎来到Django 1.6!

这些发行说明涵盖了 new features 以及一些 backwards incompatible changes 从django 1.5或更旧版本升级时,您需要注意。我们还删除了一些功能,这些功能在 our deprecation plan 我们已经 begun the deprecation process for some features .

python兼容性

django 1.6和django 1.5一样,需要python 2.6.5或更高版本。python 3也得到了官方支持。我们 强烈推荐 每个受支持的Python系列(2.6.x、2.7.x、3.2.x和3.3.x)的最新次要版本。

Django1.6将是支持python 2.6的最终版本系列;从Django1.7开始,支持的python最低版本为2.7。

不支持python 3.4,但将在django 1.7中添加支持。

Django 1.6的新功能

简化的默认项目和应用程序模板

使用的默认模板 startprojectstartapp 已经简化和现代化。这个 admin 现在在新项目中默认启用;该 sites 框架不再是。 clickjacking prevention 现在打开,数据库默认为sqlite。

如果默认模板不适合您的口味,可以使用 custom project and app templates .

改进了事务管理

Django的交易管理进行了彻底改革。默认情况下,数据库级自动提交功能现在处于打开状态。这使得事务处理更加明确,应该提高性能。不推荐使用现有的API,并引入了新的API,如中所述 transaction management docs .

持久数据库连接

Django现在支持对多个请求重用相同的数据库连接。这避免了在每次请求开始时重新建立连接的开销。为了向后兼容,默认情况下禁用此功能。看见 持久连接 了解更多细节。

在任何测试模块中发现测试

Django1.6附带了一个新的测试运行程序,允许在测试位置上有更多的灵活性。前一个运行者 (django.test.simple.DjangoTestSuiteRunner )仅在中找到测试 models.pytests.py 中的python包模块 INSTALLED_APPS .

新赛运行运动员 (django.test.runner.DiscoverRunner )使用内置的测试发现功能 unittest2 (版本) unittest 在python 2.7+标准库中,并与django捆绑在一起)。通过测试发现,可以在任何名称与模式匹配的模块中找到测试。 test*.py .

此外,测试标签提供给 ./manage.py test 要指定要运行的特定测试,现在必须是完整的python点路径(或目录路径),而不是 applabel.TestCase.test_method_name 伪路径。这允许运行代码库中任意位置的测试,而不仅仅是 INSTALLED_APPS . 有关详细信息,请参阅 Django测试 .

这种变化是向后不相容的;参见 backwards-incompatibility notes .

时区感知聚合

对…的支持 time zones 在Django引入的1.4不适用于 QuerySet.dates() :聚合始终在UTC中执行。这一限制在Django 1.6中被解除。使用 QuerySet.datetimes() 在上执行时区感知聚合 DateTimeField .

支持sqlite中的保存点

Django1.6增加了对SQLite中保存点的支持,其中一些 limitations .

BinaryField 模型场

一个新的 django.db.models.BinaryField Model字段允许在数据库中存储原始二进制数据。

geodjango表单小部件

杰德扬戈现在提供 form fields and widgets 它的地理专业领域。默认情况下,它们是基于Openlayer的,但是可以定制它们以使用任何其他JS框架。

check 添加了用于验证兼容性的管理命令

A check 添加了管理命令,使您能够验证当前配置(当前面向设置)是否与Django的当前版本兼容。

Model.save() 算法已更改

这个 Model.save() 方法现在尝试直接 UPDATE 数据库(如果实例具有主键值)。以前 SELECT 是为了确定 UPDATEINSERT 是需要的。新算法只需要一个查询来更新现有的行,而旧算法需要两个查询。见 Model.save() 了解更多详细信息。

在一些罕见的情况下,数据库在执行 UPDATE . PostgreSQL就是一个例子 ON UPDATE 返回的触发器 NULL . 在这种情况下,可以设置 django.db.models.Options.select_on_save 强制保存以使用旧算法的标志。

次要特征

  • 身份验证后端可能会引发 PermissionDenied 立即使身份验证链失败。

  • 这个 HttpOnly 可以在CSRF cookie上设置标志 CSRF_COOKIE_HTTPONLY .

  • 这个 assertQuerysetEqual() 现在检查未定义的顺序并提高 ValueError 如果发现未定义的订单。如果给定的顺序为未定义,则顺序被视为未定义 QuerySet 不是有序的,并且有多个有序的值可供比较。

  • 补充 earliest() 与…对称 latest() .

  • 除了 yearmonthday ,ORM现在支持 hourminutesecond 查找。

  • Django现在将所有 PEP 249 例外情况。

  • 的默认小工具 EmailFieldURLFieldIntegerFieldFloatFieldDecimalField 使用HTML5中可用的新类型属性 (type='email'type='url'type='number' )请注意,由于 number 当前浏览器中带有本地化数字的输入类型,Django仅在数字字段未本地化时使用。

  • 这个 number 的参数 lazy plural translations 可以在翻译时提供,而不是在定义时提供。

  • 对于自定义管理命令:通过使用 BaseCommand.can_import_settings 内部选项现在独立于在执行命令期间应处于活动状态的区域设置的处理来执行。后者现在可以受到新的 BaseCommand.leave_locale_alone 内部选项。见 管理命令和区域设置 了解更多详细信息。

  • 这个 success_url 属于 DeletionMixin 现在用它的 object__dict__ .

  • HttpResponseRedirectHttpResponsePermanentRedirect 现在提供一个 url 属性(相当于响应将重定向到的URL)。

  • 这个 MemcachedCache 缓存后端现在使用最新的 pickle 协议可用。

  • 补充 SuccessMessageMixin 它提供了 success_message 的属性 FormView 基于类。

  • 增加了 django.db.models.ForeignKey.db_constraintdjango.db.models.ManyToManyField.db_constraint 选项。

  • 嵌入在管理中的jquery库已升级到1.9.1版。

  • 联合订阅源 (django.contrib.syndication )现在可以通过传递额外的上下文来使用新的 Feed.get_context_data() 回调。

  • 管理列表列具有 column-<field_name> 在HTML中初始化,以便可以使用CSS设置列标题的样式,例如设置列宽。

  • 这个 isolation level 可以在PostgreSQL下定制。

  • 这个 blocktrans 模板标记现在尊重 TEMPLATE_STRING_IF_INVALID 对于上下文中不存在的变量,就像其他模板构造一样。

  • SimpleLazyObject S现在将在shell调试情况下提供更有用的表示。

  • 通用的 GeometryField 现在可以使用管理员中的Openlayers小部件进行编辑。

  • 文档包含 deployment checklist .

  • 这个 diffsettings 命令获得 --all 选择权。

  • django.forms.fields.Field.__init__ 现在调用 super() ,允许现场混合实现 __init__() 可靠调用的方法。

  • 这个 validate_max 参数已添加到 BaseFormSetformset_factory()ModelForm 和相同的内联版本。表单集的验证行为 max_num 已澄清。记录了以前未记录的对内存耗尽攻击进行强化的表单集行为,未记录的限制为1000或更高 max_num 表单已更改,因此总是超过1000个 max_num .

  • 补充 BCryptSHA256PasswordHasher 用bcrypt解决密码截断问题。

  • Pillow 现在是与Django一起使用的首选图像操作库。 PIL 正在等待弃用(Django 1.8中将删除支持)。要升级,您应该 first 卸载PIL, then 安装枕头。

  • ModelForm 接受几个新的 Meta 选项。

    • 包含在中的字段 localized_fields 列表将本地化(通过设置 localize 在窗体字段中)。

    • 这个 labelshelp_textserror_messages 选项可用于自定义默认字段,请参见 覆盖默认字段 有关详细信息。

  • 这个 choices 模型字段的参数现在接受iterables的iterables,而不需要列表或元组的iterables。

  • 可以使用自定义HTTP响应中的原因短语 reason_phrase .

  • 为提供下一页的URL时 django.contrib.auth.views.logout()django.contrib.auth.views.password_reset()django.contrib.auth.views.password_reset_confirm()django.contrib.auth.views.password_change() ,您现在可以传递URL名称,它们将被解析。

  • 新的 dumpdata --pks 选项指定要转储的对象的主键。此选项只能用于一个模型。

  • 补充 QuerySet 方法 first()last() 这是返回与过滤器匹配的第一个或最后一个对象的方便方法。退换商品 None 如果没有匹配的对象。

  • ViewRedirectView 现在支持HTTP PATCH 方法。

  • GenericForeignKey 现在选择一个选项 for_concrete_model 参数,当设置为 False 允许字段引用代理模型。默认值为 True 保持原有的行为。

  • 这个 LocaleMiddleware 现在,如果会话中不存在活动语言,则将其存储在会话中。这可以防止在会话刷新后丢失语言设置,例如注销。

  • SuspiciousOperation 已被划分为多个子类,每个子类都将登录到 django.security 日志记录层次结构。随着这一变化, handler400 每当 SuspiciousOperation 到达wsgi处理程序以返回 HttpResponseBadRequest .

  • 这个 DoesNotExist 异常现在包含一条消息,指示用于查找的属性的名称。

  • 这个 get_or_create() 方法不再需要至少一个关键字参数。

  • 这个 SimpleTestCase 类包括一个新的断言帮助器,用于测试表单集错误: django.test.SimpleTestCase.assertFormsetError()

  • 添加到 QuerySet 通过 select_related() 可以使用清除 select_related(None) .

  • 这个 get_extra()get_max_num() 方法对 InlineModelAdmin 可以重写以自定义额外的和最大数量的内联表单。

  • 表单集现在有一个 total_error_count() 方法。

  • ModelForm 字段现在可以通过使用 error_messages A的论证 Field 的构造函数。为了利用这个新特性和您的自定义字段, see the updated recommendation 为了养育一个 ValidationError .

  • ModelAdmin 现在,在创建、编辑或删除对象后保留列表视图上的过滤器。可以通过设置 preserve_filters 属性到 False .

  • 补充 FormMixin.get_prefix (回报) FormMixin.prefix 默认情况下)允许自定义 prefix 形式的。

  • 原始查询 (Manager.raw()cursor.execute() )现在可以使用“pyformat”参数样式,其中查询中的占位符被指定为 '%(name)s' 参数以字典而不是列表的形式传递(除了在sqlite上)。这在MySQL和PostgreSQL上一直是可能的(但没有官方支持),现在也可以在Oracle上使用。

  • pbkdf2密码散列器的默认迭代计数增加了20%。此向后兼容的更改不会影响现有密码或已子类化的用户 django.contrib.auth.hashers.PBKDF2PasswordHasher 更改默认值。密码 will be upgraded 必要时使用新的迭代计数。

1.6中的向后不兼容变化

警告

除了本节概述的更改外,请务必查看 deprecation plan 对于任何已删除的功能。如果您没有在取消预测时间线内更新给定功能的代码,则删除该功能可能会显示为向后不兼容的更改。

新的交易管理模型

行为改变

在django 1.6中,默认情况下启用数据库级自动提交。虽然这并没有改变Django事务管理的一般精神,但是有一些向后的不兼容性。

保存点和 assertNumQueries

事务管理中的更改可能会导致创建、释放或回滚保存点的附加语句。这更可能发生在sqlite上,因为直到这个版本它才支持保存点。

如果使用测试 assertNumQueries() 失败,因为查询数比预期的多,请检查额外的查询是否与保存点相关,并相应地调整预期的查询数。

PostgreSQL的自动提交选项

在以前的版本中,数据库级的自动提交只是PostgreSQL的一个选项,默认情况下它是被禁用的。此选项现在被忽略,可以删除。

新型试验转轮

为了保持与python的一致性 unittest 模块,新的测试运行程序 (django.test.runner.DiscoverRunner )不自动支持以前运行程序支持的某些类型的测试:

  • 试验 models.pytests/__init__.py 将不再找到并运行文件。将它们移到名称以开头的文件中 test .

  • 不再自动发现doctest。要在测试套件中集成doctest,请按照 recommendations in the Python documentation .

Django捆绑了 doctest python标准库中的模块(in django.test._doctest )包括一些附加的doctest实用程序。这些实用程序已弃用,将在django 1.8中删除;应更新doctest套件以使用标准库的doctest模块(或转换为 unittest -兼容测试)。

如果希望延迟对测试套件的更新,可以设置 TEST_RUNNER 设置为 django.test.simple.DjangoTestSuiteRunner 完全恢复旧的测试行为。 DjangoTestSuiteRunner 已弃用,但在1.8版之前不会从Django中删除。

移除 django.contrib.gis.tests.GeoDjangoTestSuiteRunner geodjango自定义测试运行程序

这是为了开发人员使用geodjango应用程序本身,并与上面关于测试运行程序更改的项目相关:

这个 django.contrib.gis.tests.GeoDjangoTestSuiteRunner 已删除测试运行程序,不再支持它实现的独立geodjango测试执行设置。要运行geodjango测试,只需使用 DiscoverRunner 并指定 django.contrib.gis 应用程序。

测试中的自定义用户模型

新测试运行程序的引入也略微改变了导入测试模型的方式。因此,任何重写 AUTH_USER_MODEL 使用Django的一个测试用户模型测试行为( django.contrib.auth.tests.custom_user.CustomUserdjango.contrib.auth.tests.custom_user.ExtensionUser )现在必须在测试模块中显式导入用户模型::

from django.contrib.auth.tests.custom_user import CustomUser


@override_settings(AUTH_USER_MODEL="auth.CustomUser")
class CustomUserFeatureTests(TestCase):
    def test_something(self):
        # Test code here
        ...

此导入强制注册自定义用户模型。如果没有此导入,测试将无法在自定义用户模型中进行交换,并且您将获得错误报告:

ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.CustomUser' that has not been installed

时区感知 daymonthweek_day 查找

Django 1.6引入了时区支持 daymonthweek_day 查找时 USE_TZTrue . 这些查找以前是在UTC中执行的,与当前时区无关。

这就要求 time zone definitions in the database . 如果使用sqlite,则必须安装 pytz. 如果您使用的是MySQL,则必须安装 pytz 并加载时区表 mysql_tzinfo_to_sql .

添加 QuerySet.datetimes()

time zone support 在Django中添加的1.4是活动的, QuerySet.dates() 查找返回意外结果,因为聚合是在UTC中执行的。为了解决这个问题,Django1.6引入了一个新的API, QuerySet.datetimes() . 这需要对代码进行一些更改。

QuerySet.dates() 收益率 date 对象

QuerySet.dates() 现在返回 date . 它用于返回 datetime .

QuerySet.datetimes() 返回的列表 datetime .

QuerySet.dates() no longer usable on DateTimeField

QuerySet.dates() 如果在上使用,则引发错误 DateTimeField 当时区支持处于活动状态时。使用 QuerySet.datetimes() 相反。

date_hierarchy 需要时区定义

这个 date_hierarchy 管理员的功能现在依赖于 QuerySet.datetimes() 当它用于 DateTimeField .

这需要数据库中的时区定义,当 USE_TZTrue . Learn more .

date_list 在一般视图中,需要时区定义

出于同样的原因,访问 date_list 在基于日期的通用视图的上下文中,当视图基于 DateTimeFieldUSE_TZTrue . Learn more .

新查找可能与模型字段冲突

Django 1.6介绍 hourminutesecond 查找 DateTimeField . 如果有模型字段调用 hourminutesecond ,新查找将与字段名冲突。附加显式 exact 如果这是一个问题,则查找。

BooleanField no longer defaults to False

当A BooleanField 没有明确的 default ,隐式默认值为 None . 在之前的Django版本中, False 但这并不能准确地表示缺少值。

依赖默认值的代码 False 将新模型实例保存到数据库时可能引发异常,因为 None 不是可接受的值 BooleanField . 您应该指定 default=False 在字段定义中,或确保字段设置为 TrueFalse 在保存对象之前。

模板中的翻译和注释

评论后的翻译提取

从模板中提取可翻译文本 makemessages 当I18N结构位于 {{# / #}} -在同一行上键入comment。例如。:

{# A comment #}{% trans "This literal was incorrectly ignored. Not anymore" %}

翻译意见的位置

模板中翻译人员的注释 指定使用 {{# / #}} 需要在一行的末尾。如果不是,则忽略注释,并且 makemessages 将生成警告。例如:

{# Translators: This is ignored #}{% trans "Translate me" %}
{{ title }}{# Translators: Extracted and associated with 'Welcome' below #}
<h1>{% trans "Welcome" %}</h1>

引用 reverse()

当反转URL时,Django没有应用 django.utils.http.urlquote 在将参数插入到URL模式之前。这个bug在django 1.6中被修复。如果在将参数传递给 reverse() ,这可能导致双报价。如果发生这种情况,只需从代码中删除URL引用。您还必须替换中使用的URL中的特殊字符 assertRedirects() 它们的编码版本。

在评论应用程序中存储IP地址

评论应用程序现在使用 GenericIPAddressField 用于存储注释者的IP地址,以支持从IPv6地址提交的注释。直到现在,它把它们存储在 IPAddressField ,仅用于支持IPv4。当保存来自ipv6地址的注释时,该地址将在mysql数据库中自动截断,并在Oracle上引发异常。您需要更改数据库中的列类型,才能从这一更改中获益。

对于MySQL,在项目数据库上执行此查询:

ALTER TABLE django_comments MODIFY ip_address VARCHAR(39);

对于Oracle,执行此查询:

ALTER TABLE DJANGO_COMMENTS MODIFY (ip_address VARCHAR2(39));

如果不应用此更改,行为将保持不变:在MySQL上,IPv6地址将被静默截断;在Oracle上,将生成异常。sqlite或postgresql数据库不需要更改数据库。

文字百分比 cursor.execute 查询

当运行原始SQL查询时, cursor.execute 方法,将文本百分比加倍的规则 (% )查询内部已统一。过去的行为依赖于数据库后端。现在,在所有后端,如果还提供替换参数,则只需要将文字百分比字符加倍。例如::

# No parameters, no percent doubling
cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")

# Parameters passed, non-placeholders have to be doubled
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' and id = %s", [self.id])

SQLite 用户需要检查和更新这些查询。

manytomanyfield字段的模型表单字段的帮助文本

对应于的模型表单字段的HTML呈现 ManyToManyField 用于获取硬编码句子的模型字段:

按住Mac上的“Control”(控制)或“Command”(命令),选择多个。

(或其到活动区域的翻译)如果两者都不显示,则作为帮助图例强制执行。 model 也不 form help_text 属性由用户指定(或将此字符串附加到 help_text 这是提供的)。

由于这发生在模型层,因此无法防止文本在不适用的情况下出现,例如实现不涉及键盘和/或鼠标的用户交互的表单字段。

从django 1.6开始,作为临时的向后兼容性规定,添加“hold down…”语句的逻辑已移动到模型表单字段层,并修改为仅在关联的小部件 SelectMultiple 或选定的子类。

如果使用自定义模型表单字段和/或小部件 ManyToManyField 其用户界面依赖于所述硬编码句子的自动提供的模型字段。这些表单字段实现需要通过提供自己的 help_text 属性。

使用django的应用程序 model form 设施与Django内置形式 fieldswidgets 不受影响,但需要了解 对模型表单域的帮助文本的咀嚼 ManyToManyField 领域 下面。

查询集迭代

这个 QuerySet 迭代已更改为立即将所有提取的行转换为 Model 对象。在django 1.5及更早版本中,提取的行被转换为 Model 以100为单位的对象。

现有代码可以工作,但在某些用例中,转换为对象的行数可能会发生变化。这种用法包括对查询集进行部分循环或最终执行的任何用法 __bool____contains__ .

值得注意的是,大多数数据库后端确实在1.5中一次性获取了所有行。

仍然可以将提取的行转换为 Model 通过使用 iterator() 方法。

BoundField.label_tag now includes the form's label_suffix

这与方法是一致的 Form.as_pForm.as_ul 渲染标签。

如果手动渲染 label_tag 在模板中:

{{ form.my_field.label_tag }}: {{ form.my_field }}

在升级到django 1.6时,您需要删除冒号(或者您可能使用的其他分隔符),以避免复制冒号。django 1.6中的以下模板将与django 1.5中的上述模板呈现相同的效果,但冒号将出现在 <label> 元素。

{{ form.my_field.label_tag }} {{ form.my_field }}

将呈现如下内容:

<label for="id_my_field">My Field:</label> <input id="id_my_field" type="text" name="my_field" />

如果要保持渲染的当前行为 label_tag 没有 label_suffix ,实例化窗体 label_suffix='' . 您还可以自定义 label_suffix 使用新的 label_suffix 参数对 label_tag() .

管理视图 _changelist_filters 获取参数

为了实现保存和恢复列表视图过滤器,管理视图现在传递 _changelist_filters 获取参数。如果您有自定义的管理模板,或者您的测试依赖于以前的URL,那么您必须考虑到这种更改。如果要还原为原始行为,可以设置 preserve_filters 属性到 False .

django.contrib.auth 密码重置使用base 64编码 User PK

Django的过去版本使用了 User 密码重置视图和URL中的主键 (django.contrib.auth.views.password_reset_confirm() )如果用户主键是一个整数,那么以36为基数的编码就足够了,但是,随着django 1.5中引入了自定义用户模型,这种假设可能不再成立。

django.contrib.auth.views.password_reset_confirm() 已修改为 uidb64 参数而不是 uidb36 . 如果要反转此视图,例如在自定义 password_reset_email.html 模板,确保更新代码。

一个临时的垫片,用于 django.contrib.auth.views.password_reset_confirm() 这将允许在Django 1.6之前生成的密码重置链接继续工作,已添加以提供向后兼容性;这将在Django 1.7中删除。因此,只要您的站点已经运行Django 1.6超过 PASSWORD_RESET_TIMEOUT_DAYS ,此更改将不会产生任何影响。如果不是(例如,如果您直接从Django 1.5升级到Django 1.7),则在您升级到Django 1.7或更高版本之前生成的任何密码重置链接在升级后都将不起作用。

此外,如果您有任何自定义密码重置URL,则需要通过替换来更新它们。 uidb36 具有 uidb64 和一个带斜线的图案后面的破折号。还添加 _\- 到可以匹配的字符列表 uidb64 模式。

例如::

url(
    r"^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$",
    "django.contrib.auth.views.password_reset_confirm",
    name="password_reset_confirm",
),

变成::

url(
    r"^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$",
    "django.contrib.auth.views.password_reset_confirm",
    name="password_reset_confirm",
),

您可能还需要添加垫片以支持旧样式的重置链接。使用上面的示例,您可以通过替换现有的URL来修改 django.contrib.auth.views.password_reset_confirm 具有 django.contrib.auth.views.password_reset_confirm_uidb36 同时移除 name 参数,以便它不会与新的URL冲突::

url(
    r"^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$",
    "django.contrib.auth.views.password_reset_confirm_uidb36",
),

在将应用程序部署到Django 1.6 for之后,您可以移除此URL模式 PASSWORD_RESET_TIMEOUT_DAYS

默认会话序列化已切换到JSON

从历史上看, django.contrib.sessions 使用 pickle 在将会话数据存储到后端之前对其进行序列化。如果您使用的是 signed cookie session backendSECRET_KEY 攻击者已知(Django中没有会导致泄漏的固有漏洞),攻击者可以将字符串插入到他们的会话中,当未选中该字符串时,将在服务器上执行任意代码。这样做的技术很简单,很容易在互联网上找到。尽管Cookie会话存储器对Cookie存储的数据进行签名以防止篡改,但是 SECRET_KEY 泄漏会立即升级为远程代码执行漏洞。

这种攻击可以通过使用JSON序列化会话数据而不是 pickle . 为了方便这一点,Django 1.5.3引入了一种新的设置, SESSION_SERIALIZER ,自定义会话序列化格式。为了向后兼容,此设置默认为使用 pickle 在django 1.5.3中,但是我们在1.6中将默认值更改为json。如果升级并从pickle切换到json,升级前创建的会话将丢失。虽然JSON序列化不支持所有的python对象,例如 pickle 是的,我们强烈建议使用JSON序列化会话。在检查代码以确定JSON序列化是否适用于您的应用程序时,请注意以下几点:

  • JSON需要字符串键,因此如果在 request.session .

  • 通过传递设置会话过期 datetime 值到 set_expiry() 不会像 datetime 值在JSON中不可序列化。您可以改用整数值。

会话序列化 有关详细信息的文档。

对象关系映射器更改

Django 1.6包含对ORM的许多更改。这些变化主要分为三类:

  1. 错误修复(例如,通用关系的正确联接子句、查询组合、联接提升和联接修剪修复)

  2. 准备新功能。例如,ORM现在已经为多列外键做好了内部准备。

  3. 一般清理。

这些更改可能会导致一些兼容性问题。例如,一些查询现在将生成不同的表别名。这会影响 QuerySet.extra() . 此外,一些查询现在将产生不同的结果。一个例子是 exclude(condition) 如果条件是复杂的(引用内部的多重联接) Q objects )在许多情况下,受影响的查询在Django1.5中没有产生正确的结果,但现在可以了。不幸的是,也有一些情况会产生不同的结果,但Django 1.5和1.6都不能产生正确的结果。

最后,对ORM内部API进行了许多更改。

其他

  • 这个 django.db.models.query.EmptyQuerySet 无法再实例化-它只能用作标记类来检查 none() 已被调用: isinstance(qs.none(), EmptyQuerySet)

  • 如果您的css/javascript代码用于按类型访问HTML输入小部件,则应将其作为 type='text' 小部件现在可能输出为 type='email'type='url'type='number' 取决于它们对应的字段类型。

  • 表单字段 error_messages 包含占位符的现在应始终使用命名占位符 ("Value '%(value)s' is too big" 而不是 "Value '%s' is too big" )有关占位符名称的详细信息,请参阅相应的字段文档。1.6中的变化尤其影响 DecimalFieldModelMultipleChoiceField .

  • 一些 error_messages 对于 IntegerFieldEmailFieldIPAddressFieldGenericIPAddressFieldSlugField 已取消,因为它们复制了绑定到字段的验证程序已提供的错误消息。

  • 由于表单验证工作流的更改, TypedChoiceField coerce 方法应始终返回 choices 字段属性。这一限制应在Django 1.7中再次解除。

  • 缓存后端处理超时的方式发生了变化。显式传入 timeout=None 不再导致使用默认超时。它现在将设置非过期超时。将0传递到memcache后端不再使用默认超时,现在将设置该值并立即过期。

  • 这个 django.contrib.flatpages 用于设置自定义HTTP头以进行调试的应用程序。此功能没有记录在案,使缓存无效,因此已将其及其通用实现删除,以前在 django.core.xheaders .

  • 这个 XViewMiddleware 已从移动 django.middleware.docdjango.contrib.admindocs.middleware 因为它是admindocs的一个实现细节,一般来说被证明是不可重用的。

  • GenericIPAddressField 现在只允许 blank 值如果 null 也允许使用值。创建一个 GenericIPAddressField 在哪里? blank 是允许的 null 不是将触发模型验证错误,因为 blank 值始终存储为 null . 以前,存储 blank 不允许的字段中的值 null 将在运行时导致数据库异常。

  • 如果A NoReverseMatch 在呈现模板时,方法会引发异常,不会停止该异常。例如, {{{{ obj.view_href }}}} 将导致模板呈现失败,如果 view_href() 加薪 NoReverseMatch . 没有变化 {{% url %}} 标记,它会导致模板呈现失败,就像在 NoReverseMatch 提高了。

  • django.test.Client.logout() 现在调用 django.contrib.auth.logout() 它将发送 user_logged_out() 信号。

  • Authentication views 现在按名称颠倒,而不是按其所在位置 django.contrib.auth.views . 如果使用的视图没有 name ,您应该更新 urlpatterns 使用 django.conf.urls.url()name 参数。例如::

    (r"^reset/done/$", "django.contrib.auth.views.password_reset_complete")
    

    变成::

    url(
        r"^reset/done/$",
        "django.contrib.auth.views.password_reset_complete",
        name="password_reset_complete",
    )
    
  • RedirectView 现在有一个 pattern_name 属性,该属性允许它通过反转URL来选择目标。

  • 在django 1.4和1.5中,一个空字符串无意中被认为是一个有效的密码。这意味着 set_password() 将空密码保存为不可用的密码,如 set_unusable_password() 确实如此 check_password() 总是返回 False 对于空白密码。此版本已更正:空白密码现在有效。

  • 行政管理 changelist_view 以前接受的 pop 获取参数以表示它将显示在弹出窗口中。此参数已重命名为 _popup 与其他管理视图保持一致。如果自定义模板使用以前的参数名,则应更新它们。

  • validate_email() 现在接受电子邮件地址 localhost 作为域。

  • 新的 makemessages --keep-pot 选项可防止删除临时 .pot 创建之前生成的文件 .po 文件。

  • 无证件者 django.core.servers.basehttp.WSGIServerException 已删除。使用 socket.error 由标准库提供。这一变化也在Django 1.5.5发布。

  • 签字 django.views.generic.base.RedirectView.get_redirect_url() 已经更改,现在也接受位置参数 (*args, **kwargs )任何未命名的捕获组现在将传递给 get_redirect_url() 可能导致 TypeError 如果不更新自定义方法的签名。

1.6中不推荐的功能

事务管理API

Django 1.6对事务管理进行了彻底检修,当前的API已被弃用:

  • django.middleware.transaction.TransactionMiddleware

  • django.db.transaction.autocommit

  • django.db.transaction.commit_on_success

  • django.db.transaction.commit_manually

  • 这个 TRANSACTIONS_MANAGED 设置

django.contrib.comments

Django的评论框架已被弃用,不再受支持。它将在Django 1.6和1.7中提供,并在Django 1.8中删除。大多数用户将更好地使用自定义解决方案或托管产品,如 Disqus__.

代码以前称为 django.contrib.comments`still available in an external repository`_ _.

支持8.4以上的PostgreSQL版本

2011年12月,PostgreSQL 8.2的上游支持期结束,2013年2月,PostgreSQL 8.3的上游支持期结束。因此,Django1.6将8.4设置为它正式支持的PostgreSQL最低版本。

强烈建议您使用最新版本的PostgreSQL,因为性能得到了改善,并且可以利用PostgreSQL 9.x中提供的本地流式复制。

改变到 cyclefirstof

模板系统通常会避开所有变量以避免XSS攻击。然而,由于历史上的一次事故, cyclefirstof 标记按原样呈现其参数。

Django 1.6启动了一个过程来纠正这种不一致。这个 future 模板库提供了 cyclefirstof 自动转义它们的输入。如果您正在使用这些标记,建议您在模板的顶部添加以下行,以启用新行为:

{% load cycle from future %}

或者:

{% load firstof from future %}

实现旧行为的标记已被弃用,在Django1.8中,旧行为将被新行为替换。为确保与Django的未来版本兼容,应修改现有模板以使用 future 版本。

如有必要,可以临时禁用自动转义 mark_safe(){{% autoescape off %}} .

CACHE_MIDDLEWARE_ANONYMOUS_ONLY 设置

CacheMiddlewareUpdateCacheMiddleware 仅当请求不是由登录用户发出时,才提供缓存请求的方法。这种机制在很大程度上是无效的,因为中间件正确地考虑了 Vary: Cookie HTTP头,在各种情况下都会设置此头,例如:

  • 访问会话,或

  • 使用默认开启的CSRF保护,或

  • 使用设置cookie的客户端库,例如 `Google Analytics`_ _.

这使得缓存在每个会话的基础上有效地工作,而不管 CACHE_MIDDLEWARE_ANONYMOUS_ONLY 设置。

_has_changed 小部件上的方法

如果您定义了自己的表单小部件并定义了 _has_changed 方法在小部件上,现在应该在表单字段本身上定义此方法。

module_name 模型元属性

Model._meta.module_name 重命名为 model_name . 尽管它是一个私有的API,但它将经历一个常规的拒绝路径。

get_(add|change|delete)_permission 模型元方法

Model._meta.get_(add|change|delete)_permission 方法已弃用。即使它们不是公共API的一部分,它们也将经历一个常规的反预测路径。你可以把它们换成 django.contrib.auth.get_permission_codename('action', Model._meta) 在哪里? 'action''add''change''delete' .

get_query_set and similar methods renamed to get_queryset

返回 QuerySetManager.get_query_setModelAdmin.queryset 已重命名为 get_queryset .

如果您正在编写一个实现的库,例如, Manager.get_query_set 方法,并且您需要支持旧的django版本,您应该重命名该方法并有条件地添加一个旧名称为的别名:

class CustomManager(models.Manager):
    def get_queryset(self):
        pass  # ...

    if django.VERSION < (1, 6):
        get_query_set = get_queryset

    # For Django >= 1.6, models.Manager provides a get_query_set fallback
    # that emits a warning when used.

如果您正在编写一个需要调用 get_queryset 方法和必须支持旧的Django版本,您应该编写:

get_queryset = (
    some_manager.get_query_set
    if hasattr(some_manager, "get_query_set")
    else some_manager.get_queryset
)
return get_queryset()  # etc

在自定义管理器的一般情况下,这两个管理器都实现自己的 get_queryset 方法并调用该方法,并且需要使用较旧的Django版本以及尚未更新的库,定义 get_queryset_compat 方法如下,并在经理内部使用:

class YourCustomManager(models.Manager):
    def get_queryset(self):
        return YourCustomQuerySet()  # for example

    if django.VERSION < (1, 6):
        get_query_set = get_queryset

    def active(self):  # for example
        return self.get_queryset_compat().filter(active=True)

    def get_queryset_compat(self):
        get_queryset = (
            self.get_query_set if hasattr(self, "get_query_set") else self.get_queryset
        )
        return get_queryset()

这有助于最小化所需的更改,但在子类(例如 RelatedManagers 来自Django 1.5),可能会覆盖 get_query_setget_queryset .

shortcut 视图和urlconf

这个 shortcut 视图已从移动 django.views.defaultsdjango.contrib.contenttypes.views 在1.0发布后不久,但旧位置从未被弃用。这个疏忽在Django 1.6中得到了纠正,现在您应该使用新的位置。

乌尔康夫 django.conf.urls.shortcut 也被否决。如果要将其包含在URLCONF中,只需替换:

(r"^prefix/", include("django.conf.urls.shortcut")),

用:

(
    r"^prefix/(?P<content_type_id>\d+)/(?P<object_id>.*)/$",
    "django.contrib.contenttypes.views.shortcut",
),

ModelForm without fields or exclude

以前,如果你想 ModelForm 要使用模型上的所有字段,只需省略 Meta.fields 属性,将使用所有字段。

这可能会导致安全问题,即将字段添加到模型中,并且最终用户会无意中自动进行编辑。在某些情况下,特别是在布尔字段中,这个问题可能是完全不可见的。这是一种 Mass assignment vulnerability .

因此,不推荐使用此行为,并使用 Meta.exclude 强烈反对选择。相反,表单中要包含的所有字段都应在 fields 属性。

如果这种安全性问题在您的案例中确实不适用,那么有一个快捷方式可以明确地指示应该使用所有字段-使用特殊值 "__all__" 对于字段属性:

class MyModelForm(ModelForm):
    class Meta:
        fields = "__all__"
        model = MyModel

如果你有习惯 ModelForms 这只需要在管理员中使用,还有另一个选项。管理员有自己的定义字段的方法 (fieldsets 等等),因此将字段列表添加到 ModelForm 是多余的。相反,只需省略 Meta 的内部类 ModelForm 或省略 Meta.model 属性。自从 ModelAdmin 子类知道它用于哪个模型,它可以添加必要的属性来派生一个函数 ModelForm . 这种行为也适用于早期的Django版本。

UpdateViewCreateView 没有显式字段

一般视图 CreateViewUpdateView 以及其他来源于 ModelFormMixin ,易受上述部分描述的安全问题的影响,因为它们可以自动创建 ModelForm 它使用模型的所有字段。

因此,如果使用这些视图编辑模型,还必须提供 fields 属性(在Django 1.6中是新的),它是模型字段的列表,其工作方式与 ModelForm Meta.fields 属性。或者,您可以设置 form_class 属性为 ModelForm 它明确定义了要使用的字段。定义一个 UpdateViewCreateView 不推荐使用与模型一起使用但没有显式字段列表的子类。

对模型表单域的帮助文本的咀嚼 ManyToManyField 领域

所有特殊处理 help_text 属性 ManyToManyField 由标准模型或模型表单字段执行的模型字段,如中所述 manytomanyfield字段的模型表单字段的帮助文本 上述内容已弃用,将在Django 1.8中删除。

这些字段的帮助文本需要由应用程序、自定义表单字段或小部件处理,就像其他模型字段类型一样。