Django 1.6 release notes

注意

致力于Malcolm Tredinnick

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

马尔科姆是Django的一个长期贡献者,Django是一个模范社区成员,一个聪明的头脑和一个朋友。他对Django以及许多其他开源项目的贡献几乎不可能列举。许多核心Django团队的他们的第一个补丁审查他;他的导师丰富了我们。他的考虑,耐心和奉献将永远是我们的灵感。

这个版本的Django是Malcolm的。

- Django开发人员

2013年11月6日

欢迎来到Django 1.6!

这些发行说明涵盖新功能以及一些向后不兼容更改,您需要知道从Django 1.5或更早版本升级时。我们还删除了一些功能,详情请参阅our deprecation plan,我们已开始针对某些功能的弃用流程

Python compatibility

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)的最新版本。

Django 1.6将是最终发布系列支持Python 2.6;从Django 1.7开始,最低支持的Python版本将是2.7。

不支持Python 3.4,但将在Django 1.7中添加支持。

What’s new in Django 1.6

Simplified default project and app templates

startprojectstartapp使用的默认模板已经过简化和现代化。默认情况下,在新项目中启用adminsites框架不再是。clickjacking prevention现在启用,数据库默认为SQLite。

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

Improved transaction management

Django的事务管理被大修。默认情况下,数据库级自动提交已打开。这使得事务处理更加明确,并且应该提高性能。现有的API已被弃用,并引入了新的API,如transaction management docs中所述。

Persistent database connections

Django现在支持为多个请求重用相同的数据库连接。这避免了在每个请求开始时重新建立连接的开销。为了向后兼容性,默认情况下禁用此功能。有关详细信息,请参见Persistent connections

Discovery of tests in any test module

Django 1.6附带了一个新的测试运行器,允许更多的测试位置灵活性。上一个转轮(django.test.simple.DjangoTestSuiteRunner)仅在Python包的models.pytests.py模块中发现测试在INSTALLED_APPS中。

新转轮(django.test.runner.DiscoverRunner)使用unittest2(Python 2.7中的unittest版本)中内置的测试发现功能+标准库,并与Django捆绑在一起)。使用测试发现,测试可以位于名称与模式test*.py匹配的任何模块中。

此外,提供给./ manage.py 测试以提名要运行的特定测试的测试标签现在必须是完整的Python虚线路径目录路径),而不是applabel.TestCase.test_method_name伪路径。这允许运行位于代码库任何位置的测试,而不只是在INSTALLED_APPS中。有关详细信息,请参阅Testing in Django

此更改向后不兼容;请参阅backwards-incompatibility notes

Time zone aware aggregation

在Django 1.4中引入的对time zones的支持在QuerySet.dates()中无法正常工作:聚合始终以UTC执行。这个限制在Django 1.6中解除。使用QuerySet.datetimes()DateTimeField上执行时区感知聚合。

Support for savepoints in SQLite

Django 1.6在SQLite中添加了对保存点的支持,有一些limitations

BinaryField model field

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

GeoDjango form widgets

GeoDjango现在为其地理专业字段提供form fields and widgets它们是基于OpenLayers的,默认情况下,但他们可以定制使用任何其他JS框架。

check management command added for verifying compatibility

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

Model.save() algorithm changed

如果实例具有主键值,则Model.save()方法现在将直接尝试UPDATE以前执行SELECT以确定是否需要UPDATEINSERT新算法仅需要一个查询来更新现有行,而旧算法需要两个查询。有关详细信息,请参阅Model.save()

在少数情况下,数据库在执行UPDATE时不会报告找到匹配的行。一个例子是PostgreSQL ON UPDATE触发器,返回NULL在这种情况下,可以设置django.db.models.Options.select_on_save标志,以强制保存使用旧算法。

Minor features

  • 认证后端可能会导致PermissionDenied立即使认证链失败。
  • 可以使用CSRF_COOKIE_HTTPONLY在CSRF cookie上设置HttpOnly标志。
  • assertQuerysetEqual()现在检查未定义的顺序,如果发现未定义的顺序,则会引发ValueError如果给定的QuerySet未排序,并且有多个有序值要比较,则该顺序被视为未定义。
  • 添加earliest()latest()的对称性。
  • In addition to year, month and day, the ORM now supports hour, minute and second lookups.
  • Django现在包装所有PEP-249异常。
  • EmailFieldURLFieldIntegerFieldFloatFieldDecimalField的默认小部件使用HTML5中可用的新类型属性(type='email'type='url'type='number')。请注意,由于对当前浏览器中本地化数字的number输入类型的不稳定支持,Django仅在数字字段未本地化时使用它。
  • lazy plural translationsnumber参数可以在转换时间而不是在定义时间提供。
  • 对于自定义管理命令:现在可以通过使用can_import_settings内部选项来验证在请求它的命令中是否存在有效设置,而与在命令执行期间应该处于活动状态的区域设置的处理无关。后者现在可受新的leave_locale_alone内部选项的影响。有关详细信息,请参阅Management commands and locales
  • DeletionMixinsuccess_url现在用其object__dict__进行内插。
  • HttpResponseRedirectHttpResponsePermanentRedirect现在提供了一个url属性(等同于响应将重定向到的URL)。
  • MemcachedCache缓存后端现在使用最新的pickle协议。
  • 添加了SuccessMessageMixin,它为基于FormView的类提供了success_message属性。
  • 添加了django.db.models.ForeignKey.db_constraintdjango.db.models.ManyToManyField.db_constraint选项。
  • 嵌入在管理中的jQuery库已升级到1.9.1版本。
  • 联合Feed(django.contrib.syndication)现在可以使用新的Feed.get_context_data()回调传递额外的上下文到Feed模板。
  • 管理列表列在HTML中有一个column-<field_name>类,因此列标题可以使用CSS样式,例如。以设置列宽。
  • isolation level可以在PostgreSQL下自定义。
  • 对于不存在于上下文中的变量,blocktrans模板标记现在遵守TEMPLATE_STRING_IF_INVALID,就像其他模板结构一样。
  • SimpleLazyObject现在将在shell调试情况下呈现更多有用的表示。
  • 通用GeometryField现在可以使用管理员中的OpenLayers小部件进行编辑。
  • 文档包含deployment checklist
  • diffsettings命令获得了--all选项。
  • django.forms.fields.Field.__init__现在调用super(),允许字段mixins实现__init__()
  • validate_max参数已添加到BaseFormSetformset_factory()ModelForm和内联版本中。澄清了具有max_num的formets的验证行为。记录了以前未记录的针对内存耗尽攻击硬化的行为,并更改了1000或max_num表单中较高值的未记录限制,因此始终比max_num
  • 添加了BCryptSHA256PasswordHasher以解决bcrypt的密码截断问题。
  • 枕头现在是与Django一起使用的首选图像处理库。PIL正在等待废弃(支持在Django 1.8中移除)。To upgrade, you should first uninstall PIL, then install Pillow.
  • ModelForm接受多个新的Meta选项。
    • 包含在localized_fields列表中的字段将被本地化(通过在表单字段中设置localize)。
    • labelshelp_textserror_messages选项可用于自定义默认字段,请参阅Overriding the default fields细节。
  • 模型字段的choices参数现在接受可迭代的迭代,而不需要可迭代的列表或元组。
  • 可以使用reason_phrase在HTTP响应中自定义原因短语。
  • 当提供logout()password_reset()password_reset_confirm()password_change()
  • dumpdata manage.py命令现在有一个--pks选项,将允许用户指定要转储的对象的主键。此选项只能与一个模型一起使用。
  • 添加QuerySet方法first()last()这些方便的方法返回匹配过滤器的第一个或最后一个对象。如果没有匹配的对象,则返回None
  • ViewRedirectView现在支持HTTP PATCH方法。
  • GenericForeignKey现在采用可选的for_concrete_model参数,当设置为False时,允许字段引用代理模型。默认值为True以保留旧的行为。
  • LocaleMiddleware现在将会话中存储活动语言(如果它不存在)。这防止在会话冲洗之后语言设置的丢失,例如。登出。
  • SuspiciousOperation已区分为多个子类,并且每个都将记录到django.security日志记录层次结构下的匹配命名记录器。随着这一改变,每当SuspiciousOperation到达WSGI处理程序以返回HttpResponseBadRequest时,使用handler400机制和默认视图。
  • DoesNotExist异常现在包括一条消息,指示用于查找的属性的名称。
  • get_or_create()方法不再需要至少一个关键字参数。
  • SimpleTestCase类包括一个用于测试formset错误的新断言帮助程序:assertFormsetError()
  • 可以使用select_related(None)清除通过select_related()添加到QuerySet的相关字段的列表。
  • 可以覆盖InlineModelAdmin上的get_extra()get_max_num()方法来自定义额外和最大数量的内联表单。
  • 表单现在有一个total_error_count()方法。
  • ModelForm字段现在可以使用Field的构造函数的error_messages参数覆盖模型字段中定义的错误消息。要利用您的自定义字段使用此新功能,请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密码hasher的默认迭代计数已增加了20%。此向后兼容的更改不会影响现有密码或已归入django.contrib.auth.hashers.PBKDF2PasswordHasher子类更改默认值的用户。密码will be upgraded,以根据需要使用新的迭代计数。

Backwards incompatible changes in 1.6

警告

除了本节中概述的更改外,请务必查看已删除的任何功能的deprecation plan如果您没有在指定功能的弃用时间轴内更新代码,则其移除可能会显示为向后不兼容的更改。

New transaction management model

Behavior changes

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

Savepoints and assertNumQueries

事务管理中的更改可能会导致创建,释放或回滚保存点的其他语句。这是更可能发生与SQLite,因为它不支持保存点,直到此版本。

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

Autocommit option for PostgreSQL

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

New test runner

为了与Python的unittest模块保持更大的一致性,新的测试运行器(django.test.runner.DiscoverRunner)不会自动支持上一个运行器支持的一些类型的测试:

  • 将不再找到并运行models.pytests/__init__.py文件中的测试。将它们移动到名称以test开头的文件。
  • Doctests将不再被自动发现。要将测试集成到测试套件中,请按照Python文档中的建议操作。

Django从Python标准库(在django.test._doctest)中捆绑了doctest模块的修改版本,并包含一些额外的doctest实用程序。这些实用程序已弃用,将在Django 1.8中删除; doctest套件应该更新为使用标准库的doctest模块(或转换为与unittest兼容的测试)。

如果您希望延迟更新测试套件,可以将TEST_RUNNER设置设置为django.test.simple.DjangoTestSuiteRunner,以完全恢复旧的测试行为。DjangoTestSuiteRunner is deprecated but will not be removed from Django until version 1.8.

Removal of django.contrib.gis.tests.GeoDjangoTestSuiteRunner GeoDjango custom test runner

这是为开发人员在GeoDjango应用程序本身和上面的项目相关的测试赛跑者的变化:

django.contrib.gis.tests.GeoDjangoTestSuiteRunner测试运行器已删除,并且不再支持独立的GeoDjango测试执行设置。要运行GeoDjango测试,只需使用新的DiscoverRunner并指定django.contrib.gis应用。

Custom User models in tests

新的测试运行器的引入也略微改变了导入测试模型的方式。因此,任何覆盖AUTH_USER_MODEL以使用Django的测试用户模型(CustomUserExtensionUser)测试行为的测试现在必须明确导入测试模块中的用户模型:

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

Time zone-aware day, month, and week_day lookups

对于daymonthweek_day个查询,当USE_TZTrue这些查找以前在UTC中执行,而不考虑当前时区。

这需要数据库中的time zone definitions in the database如果您使用SQLite,您必须安装pytz如果您使用的是MySQL,则必须安装pytz,并使用mysql_tzinfo_to_sql加载时区表。

Addition of QuerySet.datetimes()

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

QuerySet.dates() returns date objects

QuerySet.dates()现在返回date的列表。它用于返回datetime的列表。

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

QuerySet.dates() no longer usable on DateTimeField

QuerySet.dates() raises an error if it’s used on DateTimeField when time zone support is active. 请改用QuerySet.datetimes()

date_hierarchy requires time zone definitions

管理员的date_hierarchy功能现在在DateTimeField上使用时,依靠QuerySet.datetimes()

这在USE_TZTrue时需要数据库中的时区定义。Learn more

date_list in generic views requires time zone definitions

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

New lookups may clash with model fields

Django 1.6在DateTimeField上引入hourminutesecond如果您有名为hourminutesecond的模型字段,新的查找将与您的字段名称冲突。如果这是一个问题,请附加显式的exact查询。

BooleanField no longer defaults to False

BooleanField没有显式的default时,隐式默认值为None在以前的Django版本中,它是False,但是没有准确表示缺少值。

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

Translations and comments in templates

Extraction of translations after comments

使用makemessages命令从模板中提取可翻译文字现在可以正确检测i18n结构位于{# / #}在同一行。例如。

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

Location of translator comments

Comments for translators in templates specified using {# / #} need to be at the end of a line. 如果不是,则忽略注释,makemessages将生成警告。例如:

{##}{% trans "Translate me" %}
{{ title }}{##}
<h1>{% trans "Welcome" %}</h1>

Quoting in reverse()

当翻转网址时,Django在网址格式中插入参数之前未将urlquote()应用于参数。这个bug在Django 1.6中修复。如果您通过在传递参数到reverse()之前应用网址引用来解决此错误,则可能会导致双引号。如果发生这种情况,只需从代码中删除网址引用。您还必须用其编码版本替换assertRedirects()中使用的网址中的特殊字符。

Storage of IP addresses in the comments app

评论应用程序现在使用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数据库不需要更改数据库。

Percent literals in cursor.execute queries

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

# 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用户需要检查和更新此类查询。

Help text of model form fields for ManyToManyField fields

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

Hold down “Control”, or “Command” on a Mac, to select more than one.

(or its translation to the active locale) imposed as the help legend shown along them if neither model nor form help_text attributes were specified by the user (or this string was appended to any help_text that was provided).

因为这发生在模型层,所以没有办法防止文本在不适用的情况下出现,例如实现不涉及键盘和/或鼠标的用户交互的表单域。

从Django 1.6开始,作为一种特殊的临时向后兼容性规定,添加“Hold down ...”句子的逻辑已经移动到模型表单字段层,并被修改为仅当相关的小部件SelectMultiple或选择的子类。

如果您为ManyToManyField模型字段使用自定义模型表单字段和/或窗口小部件,其UI依赖于自动提供的上述硬编码语句,则该更改可能以向后不兼容的方式影响您。这些表单字段实现需要通过提供自己的help_text属性处理来适应新的场景。

使用Django model form设施以及Django内置形式fieldswidgets的应用程序不受影响,但需要了解所描述的内容在Munging of help text of model form fields for ManyToManyField fields下面。

QuerySet iteration

QuerySet迭代已更改为立即将所有获取的行转换为Model对象。在Django 1.5和更早版本中,获取的行转换为大小为100的Model对象。

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

值得注意的是,大多数数据库后端已经在1.5中一次性提取所有行。

仍然可以使用iterator()方法将提取的行延迟转换为Model对象。

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时重复它。除了冒号将出现在<label>元素中,Django 1.6中的以下模板将与Django 1.5中的上述模板完全相同。

{{ 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_suffixlabel_tag的行为,请实例化形式label_suffix=''您还可以使用label_tag()上的新label_suffix参数,在每个字段基础上自定义label_suffix

Admin views _changelist_filters GET parameter

为了实现保留和恢复列表视图过滤器,管理视图现在传递_changelist_filters GET参数。如果您有自定义管理模板,或者您的测试依赖于之前的网址,请记住这一变化。如果要恢复原始行为,可以将preserve_filters属性设置为False

django.contrib.auth password reset uses base 64 encoding of User PK

过去版本的Django在密码重置视图和URL(django.contrib.auth.views.password_reset_confirm())中使用User主键的第36个编码。如果用户主键是整数,则Base 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中删除。因此,只要您的网站在超过PASSWORD_RESET_TIMEOUT_DAYS的情况下运行Django 1.6,此更改就不会生效。如果没有(例如,如果您直接从Django 1.5升级到Django 1.7),则在升级到Django 1.7或更高版本之前生成的任何密码重置链接在升级后将不起作用。

此外,如果您有任何自定义密码重置网址,则需要更新它们,方法是将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'),

您还可以添加垫片以支持旧样式重置链接。使用上述示例,您可以使用django.contrib.auth.views.password_reset_confirm_uidb36替换django.contrib.auth.views.password_reset_confirm来修改现有的网址,同时删除name参数,因此它与新网址不冲突:

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

您可以在使用Django 1.6为PASSWORD_RESET_TIMEOUT_DAYS部署应用程式后,移除此网址格式。

Default session serialization switched to JSON

历史上,django.contrib.sessions使用pickle将会话数据序列化,然后将其存储在后端。如果您使用的是signed cookie session backend,而且SECRET_KEY已被攻击者所知(Django没有固有的漏洞会导致漏洞)攻击者可以在他的会话中插入一个字符串,当它取消绑定时,在服务器上执行任意代码。这样做的技术是简单和容易在互联网上。虽然cookie会话存储签名cookie存储的数据,以防止篡改,SECRET_KEY泄漏立即升级到远程代码执行漏洞。

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

  • JSON需要字符串键,因此如果您在request.session中使用非字符串键,您可能会遇到问题。
  • 通过将datetime值传递到set_expiry()来设置会话过期将无法工作,因为datetime值不能在JSON中序列化。您可以使用整数值。

有关详细信息,请参阅Session serialization文档。

Object Relational Mapper changes

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

  1. 修正错误(例如通用关系的正确连接子句,查询组合,连接提升和连接修剪修复)
  2. 新功能的准备。例如,ORM现在内部准备好用于多列外键。
  3. 一般清理。

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

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

Miscellaneous

  • django.db.models.query.EmptyQuerySet不能再被实例化 - 它只能用作检查none()是否被调用的标记类: isinstance(qs.none(), EmptyQuerySet)

  • If your CSS/JavaScript code used to access HTML input widgets by type, you should review it as type='text' widgets might be now output as type='email', type='url' or type='number' depending on their corresponding field type.

  • Form field’s error_messages that contain a placeholder should now always use a named placeholder ("Value '%(value)s' is too big" instead of "Value '%s' is too big"). 有关占位符名称的详细信息,请参阅相应的字段文档。1.6中的更改特别影响DecimalFieldModelMultipleChoiceField

  • Some error_messages for IntegerField, EmailField, IPAddressField, GenericIPAddressField, and SlugField have been suppressed because they duplicated error messages already provided by validators tied to the fields.

  • 由于表单验证工作流程中的更改,TypedChoiceField coerce方法应始终返回choices字段属性中显示的值。这个限制应该在Django 1.7中再次提升。

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

  • 用于设置自定义HTTP标头以供调试的django.contrib.flatpages应用程序。此功能未记录,并使缓存无效,因此已被删除,以及其通用实现,以前在django.core.xheaders中可用。

  • XViewMiddleware已从django.middleware.doc移至django.contrib.admindocs.middleware,因为它是admindocs的实施细节,经过验证不可重复使用。

  • GenericIPAddressField现在只允许blank值,如果null值也允许。创建GenericIPAddressField其中blank但允许null不会触发模型验证错误,因为blank存储为null以前,在不允许null的字段中存储blank值会在运行时导致数据库异常。

  • 如果在渲染模板时从方法引发了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中的位置。If you are using the views without a name, you should update your urlpatterns to use url() with the name parameter. 例如:

    (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 GET参数,表示它将显示在弹出式窗口中。此参数已重命名为_popup,以与其余管理视图一致。如果自定义模板使用之前的参数名称,则应更新自定义模板。

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

  • --keep-pot选项已添加到makemessages,以防止django在创建.po文件之前删除其生成的临时.pot文件。

  • 未记录的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

Features deprecated in 1.6

Transaction management APIs

事务管理在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的代码仍然在外部存储库中可用。

Support for PostgreSQL versions older than 8.4

上游支持期的结束在2011年12月达到了PostgreSQL 8.2,2013年2月达到了8.3。因此,Django 1.6将8.4设置为它正式支持的最小PostgreSQL版本。

强烈建议您使用最新版本的PostgreSQL,因为性能改进,并利用PostgreSQL 9.x中提供的本地流复制。

Changes to cycle and firstof

模板系统通常转义所有变量以避免XSS攻击。然而,由于历史的意外,cyclefirstof

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

{% load cycle from future %}

要么:

{% load firstof from future %}

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

如有必要,您可以暂时使用mark_safe(){% autoescape off %}

CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting

CacheMiddlewareUpdateCacheMiddleware用于提供一种缓存请求的方法,前提是这些请求不是由登录用户发出的。这种机制很大程度上无效,因为中间件正确地考虑了Vary: Cookie HTTP头,并且这个头被设置在各种场合,如:

  • 访问会话,或
  • 使用默认情况下打开的CSRF保护或
  • 使用设置Cookie的客户端库,如Google Analytics

这使得高速缓存基于每个会话有效地工作,而不管CACHE_MIDDLEWARE_ANONYMOUS_ONLY设置。

_has_changed method on widgets

如果您定义了自己的窗体小部件并在窗口小部件上定义了_has_changed方法,那么现在应该在窗体字段上定义此方法。

module_name model _meta attribute

Model._meta.module_name已重命名为model_name尽管是一个私有API,它将通过一个常规的弃用路径。

get_(add|change|delete)_permission model _meta methods

Model._meta.get_(add|change|delete)_permission方法已弃用。即使它们不是公共API的一部分,他们也将通过常规的弃用路径。You can replace them with django.contrib.auth.get_permission_codename('action', Model._meta) where 'action' is 'add', 'change', or 'delete'.

get_query_set and similar methods renamed to get_queryset

返回QuerySet(例如Manager.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版本和尚未更新的库的一般情况下,定义a get_queryset_compat方法,并在内部使用到您的经理:

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

    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()

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

shortcut view and URLconf

在1.0版本后不久,shortcut视图从django.views.defaults移动到django.contrib.contenttypes.views,但旧位置从来没有被淘汰。这个疏忽在Django 1.6中得到纠正,您现在应该使用新位置。

URLconf 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属性,并使用所有字段。

这可能导致安全问题,其中字段被添加到模型中,并且无意地,最终用户自动地可编辑。在某些情况下,特别是对于布尔字段,这个问题可能是完全不可见的。这是批量指派漏洞的一种形式。

因此,此行为已被弃用,并且强烈建议您不要使用Meta.exclude选项。而是,应该在fields属性中明确列出要包含在表单中的所有字段。

如果此安全问题确实不适用于您的情况,则有一个快捷方式可显式指示应使用所有字段 - 对于fields属性使用特殊值"__all__"

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

如果您有需要在管理中使用的自定义ModelForms,则还有另一个选项。管理员有自己的方法来定义字段(fieldsets等)。),因此向ModelForm添加字段列表是多余的。而只需省略ModelFormMeta内部类,或省略Meta.model属性。由于ModelAdmin子类知道它所使用的模型,因此它可以添加必要的属性来派生一个运行的ModelForm此行为也适用于早期的Django版本。

UpdateView and CreateView without explicit fields

通用视图CreateViewUpdateView以及从ModelFormMixin派生的任何内容都容易受到上述部分所述的安全问题的影响,因为他们可以自动创建使用模型的所有字段的ModelForm

For this reason, if you use these views for editing models, you must also supply the fields attribute (new in Django 1.6), which is a list of model fields and works in the same way as the ModelForm Meta.fields attribute. 或者,您可以将form_class属性设置为明确定义要使用的字段的ModelForm定义要与模型一起使用但没有显式字段列表的UpdateViewCreateView子类已弃用。

Munging of help text of model form fields for ManyToManyField fields

All special handling of the help_text attribute of ManyToManyField model fields performed by standard model or model form fields as described in Help text of model form fields for ManyToManyField fields above is deprecated and will be removed in Django 1.8.

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