Django 1.7 release notes

2014年9月2日

欢迎来到Django 1.7!

这些发行说明涵盖新功能以及一些向后不兼容更改,您需要知道从Django 1.6或更早版本升级时。我们已开始对某些功能的弃用过程,某些功能已达到其弃用过程的结束,并且已删除

Python compatibility

Django 1.7需要Python 2.7或更高版本,但我们强烈推荐最新的小版本。支持Python 2.6已被删除,并且添加了对Python 3.4的支持。

此更改应仅影响少量的Django用户,因为目前大多数操作系统供应商都提供Python 2.7或更低版​​本作为其默认版本。如果你仍然使用Python 2.6,你需要坚持Django 1.6,直到你可以升级你的Python版本。根据our support policy,Django 1.6将继续接收安全支持,直到发布Django 1.8。

What’s new in Django 1.7

Schema migrations

Django现在已经内置了对模式迁移的支持。它允许通过创建表示模型更改的迁移文件来更新,更改和删除模型,并且可以在任何开发,分阶段或生产数据库上运行。

迁移在their own documentation中介绍,但其中一些主要功能如下:

  • syncdb已弃用,并替换为migrate别担心,对syncdb的呼叫仍会像以前一样工作。

  • 新的makemigrations命令提供了一种自动检测模型更改并为其进行迁移的简单方法。

    pre_syncdbpost_syncdb已弃用,分别替换为pre_migratepost_migrate这些新信号具有稍微不同的参数。有关详细信息,请查看文档。

  • 数据库路由器上的allow_syncdb方法现在称为allow_migrate,但仍执行相同的功能。具有allow_syncdb方法的路由器仍然可以工作,但是该方法名称已过时,您应该尽快更改它(不需要重命名)。

  • initial_data fixtures are no longer loaded for apps with migrations; if you want to load initial data for an app, we suggest you create a migration for your application and define a RunPython or RunSQL operation in the operations section of the migration.

  • 具有迁移的应用程序的测试回滚行为不同;特别是,除非特别要求,否则Django将不再模拟非事务性数据库或TransactionTestCase unless specifically requested

  • 不建议在没有迁移的应用程序依赖(具有迁移的ForeignKeyManyToManyField)应用程序。有关更多信息,请参阅dependencies documentation

  • 如果您要从South升级,请参阅我们的Upgrading from South文档,第三方应用程序作者应阅读South 1.0发行说明,了解有关如何支持South和Django的详细信息迁移。

App-loading refactor

历史上,Django应用程序与模型紧密相连。一个称为“应用程序缓存”的单例处理已安装的应用程序和模型。模型模块用作许多API中的应用程序的标识符。

作为Django applications的概念,此代码显示了一些缺点。它已被重构到一个“应用程序注册表”,其中模型模块不再具有中心角色,并且可以将配置数据附加到应用程序。

到目前为止的改进包括:

  • 应用程序可以在启动时运行代码,在Django做任何其他事情之前,使用它们的配置的ready()方法。
  • 即使应用程序标签在models.py之外定义,也会正确分配给模型。您不必再显式设置app_label
  • 如果应用程序没有任何模型,则可以完全省略models.py
  • 应用程序可以使用应用程序配置的label属性重新标记,以解决标签冲突。
  • 应用程序名称可以在admin中使用应用程序配置的verbose_name进行自定义。
  • 当Django启动时,管理员会自动调用autodiscover()因此,您可以从URLconf中删除此行。
  • Django通过一个确定性和直接的过程,立即导入所有应用程序配置和模型。这应该使得更容易诊断导入问题,如导入循环。

New method on Field subclasses

为帮助同时实现模式迁移以及在将来的Django版本中更轻松地添加复合键,Field API现在有一个新的必需方法:deconstruct()

此方法不带参数,并返回四个项目的元组:

  • name:字段在其父模型上的属性名称,如果不是模型的一部分,则为None
  • path:这个字段的类的一个虚线的Python路径,包括类名。
  • args:位置参数,作为列表
  • kwargs:关键字参数,作为字典

这四个值允许将任何字段序列化为文件,以及允许字段被安全地复制,这两个新特征的必要部分。

此更改不应影响您,除非您编写自定义字段子类;如果您这样做,如果您的子类以任何方式更改__init__的方法签名,则可能需要重新实现deconstruct()方法。如果您的字段仅继承自内置的Django字段,并且不覆盖__init__,则无需进行任何更改。

如果你需要重写deconstruct(),一个好的开始的地方是内置的Django字段(django/db/models/fields/__init__.py)as几个字段,包括DecimalFieldDateField,覆盖它并显示如何在超类上调用该方法,只需添加或删除额外的参数。

这也意味着字段的所有参数本身必须是可序列化的;看看我们认为可序列化,并了解如何使自己的类可序列化,阅读migration serialization documentation

Calling custom QuerySet methods from the Manager

历史上,建议的可重用模型查询的方法是在自定义Manager类上创建方法。此方法的问题是,在第一个方法调用之后,您将返回一个QuerySet实例,并且无法调用其他自定义管理器方法。

虽然没有记录,但通常通过创建自定义QuerySet来解决这个问题,以便可以链接自定义方法;但解决方案有一些缺点:

  • 在第一次调用values()values_list()后,自定义QuerySet及其自定义方法丢失。
  • Writing a custom Manager was still necessary to return the custom QuerySet class and all methods that were desired on the Manager had to be proxied to the QuerySet. 整个过程违反了DRY原则。

QuerySet.as_manager()类方法现在可以直接使用QuerySet方法create Manager with QuerySet methods

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

Using a custom manager when traversing reverse relations

现在可以在遍历反向关系时specify a custom manager

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

New system check framework

我们添加了一个新的System check framework,用于检测常见问题(如无效模型)并提供解决这些问题的提示。框架是可扩展的,因此您可以为自己的应用和库添加自己的检查。

要执行系统检查,请使用check管理命令。此命令替换旧的validate管理命令。

Admin shortcuts support time zones

管理员中日期和时间输入小工具旁边的“今天”和“现在”快捷方式现在在current time zone中运行。以前,他们使用浏览器时区,这可能导致在不匹配服务器上的当前时区时保存错误的值。

此外,当浏览器和服务器时区不同时,窗口小部件现在显示帮助消息,以说明如何解释在字段中插入的值。

Using database cursors as context managers

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

Custom lookups

现在可以为ORM编写自定义查找和转换。自定义查找的工作方式与Django的内置查找(例如lteicontains),而转换是一个新概念。

django.db.models.Lookup类提供了一种为模型字段添加查找运算符的方法。作为示例,可以为DateFields添加day_lte运算符。

django.db.models.Transform类允许在最终查找之前转换数据库值。例如,可以写一个year变换,从字段的值提取年份。变换允许链接。在将year变换添加到DateField之后,可以对变换的值进行过滤,例如qs.filter(author__birthdate__year__lte=1981)

有关自定义查找和转换的详细信息,请参阅custom lookups文档。

Improvements to Form error handling

Form.add_error()

以前有两种主要模式用于处理表单中的错误:

  • 在某些函数(例如,函数)中提升ValidationErrorField.clean()Form.clean_<fieldname>()Form.clean()
  • Form.clean()中定位特定字段时添加Form._errors或在“干净”方法之外添加错误直接从一个视图)。

使用前一种模式是直接的,因为形式可以从上下文猜测。哪个方法引发异常),错误属于哪里,并自动处理它们。这仍然是在可能的情况下添加错误的规范方式。然而,后者是轻率和容易出错的,因为处理边缘情况的负担落在用户身上。

新的add_error()方法允许从任何地方向特定表单字段添加错误,而无需担心细节,例如创建django.forms.utils.ErrorList的实例或处理与Form.cleaned_data这个新的API取代了操作Form._errors,现在成为一个私有API。

有关使用Form.add_error()的示例,请参见Cleaning and validating fields that depend on each other

Error metadata

The ValidationError constructor accepts metadata such as error code or params which are then available for interpolating into the error message (see Raising ValidationError for more details); however, before Django 1.7 those metadata were discarded as soon as the errors were added to Form.errors.

Form.errors and django.forms.utils.ErrorList now store the ValidationError instances so these metadata can be retrieved at any time through the new Form.errors.as_data method.

然后,可以通过它们的错误code来识别检索到的ValidationError实例,这使得当给定错误存在时,可以重写错误的消息或在视图中写入自定义逻辑。它也可以用于以自定义格式(例如XML)序列化错误。

新的Form.errors.as_json()方法是一个方便的方法,它返回错误消息以及序列化为JSON的错误代码。as_json()使用as_data(),并给出如何扩展新系统的想法。

Error containers and backward compatibility

Heavy changes to the various error containers were necessary in order to support the features above, specifically Form.errors, django.forms.utils.ErrorList, and the internal storages of ValidationError. 用于存储错误字符串的这些容器现在存储ValidationError实例和公共API,已尽可能使其尽可能透明,但如果您已使用私有API,某些更改是向后不兼容;有关详细信息,请参阅ValidationError constructor and internal storage

Minor features

django.contrib.admin

django.contrib.auth

django.contrib.formtools

  • WizardView.done()的调用现在包括form_dict,以允许根据步骤名称更容易地访问表单。

django.contrib.gis

  • 窗口小部件中包含的默认OpenLayers库版本已从2.11更新到2.13。
  • Prepared geometries now also support the crosses, disjoint, overlaps, touches and within predicates, if GEOS 3.3 or later is installed.

django.contrib.messages

django.contrib.redirects

django.contrib.sessions

  • "django.contrib.sessions.backends.cached_db"会话后端现在尊重SESSION_CACHE_ALIAS在以前的版本中,它始终使用默认缓存。

django.contrib.sitemaps

django.contrib.sites

django.contrib.staticfiles

django.contrib.syndication

  • The Atom1Feed syndication feed’s updated element now utilizes updateddate instead of pubdate, allowing the published element to be included in the feed (which relies on pubdate).

Cache

  • 现在可以通过django.core.cache.caches访问在CACHES中配置的缓存。这个dict-like对象提供了每个线程一个不同的实例。它取代django.core.cache.get_cache(),现已弃用。
  • 如果直接实例化缓存后端,请注意,它们不再是线程安全的,因为django.core.cache.caches现在每个线程产生不同的实例。
  • CACHES设置的TIMEOUT参数定义为None将默认将缓存键设置为“未到期”。以前,只能将timeout=None传递给缓存后端的set()方法。

Cross Site Request Forgery

Email

  • send_mail()现在接受用于发送多部分text/plaintext/html电子邮件的html_message参数。
  • SMTP EmailBackend现在接受timeout参数。

File Storage

  • 以前在Windows上的文件锁定依赖于PyWin32包;如果没有安装,文件锁定失败。该依赖关系已被删除,并且文件锁定现在在Windows和Unix上实现。

File Uploads

  • 新的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安全版本中进行。

Forms

  • The <label> and <input> tags rendered by RadioSelect and CheckboxSelectMultiple when looping over the radio buttons or checkboxes now include for and id attributes, respectively. 每个单选按钮或复选框都包含一个id_for_label属性,以输出元素的ID。
  • The <textarea> tags rendered by Textarea now include a maxlength attribute if the TextField model field has a max_length.
  • Field.choices现在允许您通过包含带有空字符串的元组或None来为自定义标签定制“空选项”标签。在这种情况下,将省略默认空白选项"----------"
  • MultiValueField通过将require_all_fields参数设置为False来允许可选子字段。将遵守每个单个字段的required属性,并且当任何必填字段为空时,将引发新的incomplete验证错误。
  • 表单上的clean()方法不再需要返回self.cleaned_data如果它返回一个更改的字典,那么仍然会使用。
  • 在Django 1.6中进行临时回归之后,现在可以再次使TypedChoiceField coerce方法返回任意值。
  • SelectDateWidget.months可用于自定义在选择窗口小部件中显示的月份的字词。
  • min_numvalidate_min参数添加到formset_factory(),以允许验证最少数量的提交的表单。
  • FormModelForm使用的元类已重做,以支持更多继承场景。只要ModelForm首先出现在MRO中,先前限制同时阻止继承FormModelForm
  • 现在可以通过将名称设置为None,在子类化时从Form中删除该字段。
  • 现在可以自定义ModelFormuniqueunique_for_dateunique_together约束的错误消息。In order to support unique_together or any other NON_FIELD_ERROR, ModelForm now looks for the NON_FIELD_ERROR key in the error_messages dictionary of the ModelForm’s inner Meta class. 有关详细信息,请参阅有关模型的error_messages的considerations regarding model’s error_messages

Internationalization

  • django.middleware.locale.LocaleMiddleware.response_redirect_class属性允许您自定义中间件发出的重定向。
  • LocaleMiddleware现在使用会话密钥_language存储用户选择的语言。这应该只能使用LANGUAGE_SESSION_KEY常量访问。以前,它与键django_language存储,并且LANGUAGE_SESSION_KEY常量不存在,但为Django保留的键应以下划线开始。对于向后兼容性django_language仍从1.7读取。会话将在写入时迁移到新密钥。
  • blocktrans标签现在支持trimmed选项。此选项将从{% blocktrans %}的内容的开头和结尾删除换行符。标签,在行的开始和结束处替换任何空格,并使用空格字符将所有行合并为一个,以将它们分隔开。这对缩进{% blocktrans %}标记而不缩进缩进字符的内容非常有用在PO文件中的相应条目中,这使得翻译过程更容易。
  • 当您从项目的根目录运行makemessages时,任何提取的字符串现在将自动分发到正确的应用程序或项目消息文件。有关详细信息,请参见Localization: how to create language files
  • makemessages命令现在总是将--previous命令行标志添加到msgmerge命令,将之前翻译过的字符串保存在po文件中用于模糊字符串。
  • 以下设置用于调整语言Cookie选项:LANGUAGE_COOKIE_AGELANGUAGE_COOKIE_DOMAINLANGUAGE_COOKIE_PATH
  • 为世界语添加了format definitions

Management Commands

  • django-admin--no-color选项允许禁用管理命令输出的着色。

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

  • 不再需要为createcachetable命令提供高速缓存表名称或--database选项。Django从您的设置文件中获取此信息。如果已配置多个高速缓存或多个数据库,则将创建所有高速缓存表。

  • runserver命令有几个改进:

    • On Linux systems, if pyinotify is installed, the development server will reload immediately when a file is changed. 以前,它轮询文件系统每秒更改一次。这在笔记本电脑上重新加载和减少电池寿命之前造成了一个小的延迟。
    • 另外,开发服务器在翻译文件被更新时自动重新加载,即运行compilemessages后。
    • 所有HTTP请求都记录到控制台,包括对静态文件的请求或过滤掉的favicon.ico
  • 如果安装并激活了ANSICON第三方工具,管理命令现在可以在Windows下生成语法颜色输出。

  • 现在在Windows NT 6(Windows Vista和更高版本)上支持带有符号链接选项的collectstatic命令。

  • Providing initial SQL data现在可以更好地运行sqlparse Python库安装。

    请注意,为了支持RunSQL迁移操作,它已被弃用,这有助于改进的行为。

Models

  • 添加了QuerySet.update_or_create()方法。
  • 新的default_permissions模型Meta选项允许您自定义(或禁用)默认添加,更改和删除权限的创建。
  • 用于Multi-table inheritance的显式OneToOneField现在在抽象类中发现。
  • It is now possible to avoid creating a backward relation for OneToOneField by setting its related_name to '+' or ending it with '+'.
  • F expressions支持幂运算符(**)。
  • The remove() and clear() methods of the related managers created by ForeignKey and GenericForeignKey now accept the bulk keyword argument to control whether or not to perform operations in bulk (i.e. 使用QuerySet.update())。默认为True
  • 现在可以使用None作为iexact查询的查询值。
  • 当定义ForeignKeyManyToManyField时,现在可以将可调用作为属性limit_choices_to的值传递。
  • QuerySet.values()的结果调用only()defer()现在引发错误在数据库错误或不正确的数据)。
  • 指定单个字段集时,可以使用单个列表index_together(而不是列表列表)。
  • 如果您通过设置新的ManyToManyField.through_fields来明确指定应使用哪些外键,那么现在允许对具有多个外键的任何模型参与多对多关系的自定义中间模型>参数。
  • 将模型实例分配给非关系字段现在将抛出错误。以前,这用于工作,如果字段接受整数作为输入,因为它采取主键。
  • 整数字段现在根据数据库后端特定的最小值和最大值,根据它们的internal_type进行验证。先前的模型字段验证未阻止其关联的列数据类型范围中的值被保存,导致完整性错误。
  • 现在可以通过使用其属性名称来显式地order_by()关系_id字段。

Signals

  • enter参数已添加到setting_changed信号。
  • 现在可以使用'app_label.ModelName'表单的str连接到模型信号 - 就像相关字段一样 - 来延迟引用它们的发件人。

Templates

  • Context.push()方法现在返回一个上下文管理器,在退出with语句时自动调用pop()此外,push()现在接受传递给用于构建新上下文级别的dict构造函数的参数。
  • 新的Context.flatten()方法将一个Context的堆栈作为一个平面字典返回。
  • Context objects can now be compared for equality (internally, this uses Context.flatten() so the internal structure of each Context‘s stack doesn’t matter as long as their flattened version is identical).
  • widthratio模板标签现在接受"as"参数以捕获变量中的结果。
  • include模板标签现在还将接受任何具有render()方法(例如Template)作为参数的任何内容。将始终使用get_template()查找字符串参数。
  • 现在可以递归地include模板。
  • TEMPLATE_DEBUGTrue时,模板对象现已设置原始属性。这允许在django.template基础结构之外检查和记录模板起点。
  • TypeError异常在模板渲染过程中不再保持沉默。
  • 以下函数现在接受dirs参数,该参数是用于覆盖TEMPLATE_DIRS的列表或元组:
  • The time filter now accepts timezone-related format specifiers 'e', 'O' , 'T' and 'Z' and is able to digest time-zone-aware datetime instances performing the expected rendering.
  • cache标签现在将尝试使用名为“template_fragments”的高速缓存(如果存在),否则使用默认高速缓存。它现在还接受可选的using关键字参数来控制其使用的高速缓存。
  • 新的truncatechars_html过滤器会将字符串截断为不超过指定的字符数,并考虑HTML。

Requests and Responses

Tests

  • DiscoverRunner有两个新属性:test_suitetest_runner,这有助于覆盖收集和运行测试的方式。
  • fetch_redirect_response参数已添加到assertRedirects()由于测试客户端无法获取外部网址,因此您可以对不是Django应用程序一部分的重定向使用assertRedirects
  • assertRedirects()中进行比较时正确处理方案。
  • Client的所有请求方法中添加了secure参数。如果True,则请求将通过HTTPS进行。
  • assertNumQueries()现在打印出执行查询的列表,如果断言失败。
  • 由测试处理程序生成的WSGIRequest实例现在附加到django.test.Response.wsgi_request属性。
  • 用于测试的数据库设置已收集到名为TEST的字典中。

Utilities

  • 改进了strip_tags()的准确性(但仍然无法保证HTML安全的结果,如文档中所述)。

Validators

  • RegexValidator现在接受可选的flags和布尔inverse_match参数。The inverse_match attribute determines if the ValidationError should be raised when the regular expression pattern matches (True) or does not match (False, by default) the provided value. flags属性设置编译正则表达式字符串时使用的标志。
  • URLValidator现在接受可选的schemes参数,允许自定义接受的URI方案(而不是默认值http(s)ftp(s))。
  • validate_email()现在接受具有IPv6文字的地址,如RFC 5321中指定的example@[2001:db8::1]

Backwards incompatible changes in 1.7

警告

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

allow_syncdb/allow_migrate

尽管Django仍然会查看allow_syncdb方法,即使它们应该重命名为allow_migrate,但是在将模型传递给这些方法时存在微妙的差别。

对于包含迁移的应用,allow_migrate现在将通过historical models,这是没有自定义属性,方法或管理器的特殊版本模型。请确保您的allow_migrate方法仅指向model._meta中的字段或其他项目。

initial_data

具有迁移功能的应用在完成迁移后将无法加载initial_data灯具。不进行迁移的应用会在migrate阶段(将模拟旧的syncdb行为)中继续加载这些工具,但任何新应用都不会有此支持。

相反,如果需要,您可以在迁移中加载初始数据(使用RunPython操作和模型类);这具有附加的优点,即您的初始数据不需要在每次更改模式时更新。

此外,与Django的其他旧的syncdb代码一样,initial_data已从弃用路径开始,并将在Django 1.9中删除。

deconstruct() and serializability

Django现在要求所有Field类和它们的所有构造函数参数都是可序列化的。如果您以任何方式修改自定义字段中的构造函数签名,则需要实现deconstruct()方法;我们已通过instructions on implementing this method扩展了自定义字段文档。

要求所有字段参数为serializable意味着任何传递到Field构造函数(如自定义存储子类)的自定义类实例需要有一个deconstruct method defined on them as well,虽然Django提供了一个方便的类装饰器,将适用于大多数应用程序。

App-loading changes

Start-up sequence

Django 1.7一旦启动就加载应用程序配置和模型。虽然这种行为更直接,被认为是更强大,回归不能排除。有关您可能遇到的一些问题的解决方案,请参见Troubleshooting

Standalone scripts

如果您在纯Python脚本(而不是管理命令)中使用Django,而且您依赖于 DJANGO_SETTINGS_MODULE环境变量,则必须在开始时显式初始化Django的脚本与:

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

否则,您将遇到AppRegistryNotReady异常。

WSGI scripts

直到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异常。

App registry consistency

不再可能有多个已安装的应用程序具有相同的标签。在以前的Django版本中,这并不总是正确工作,但也没有崩溃。

如果您有两个具有相同标签的应用,则应为其中一个应用创建AppConfig,并覆盖其label然后,您应该调整您的代码,无论它引用此应用程序或其模型与旧标签。

不可能通过不同的路径两次导入相同的模型。从Django 1.6开始,只有当您手动将目录和子目录放在 PYTHONPATH上时,才会发生这种情况。有关迁移说明,请参阅1.4 release notes中有关新项目布局的部分。

你应该确保:

  • 所有模型都在INSTALLED_APPS中列出的应用程序中定义或具有显式app_label
  • 模型不会作为加载应用程序的副作用导入。具体来说,您不应在应用程序的根模块中或在定义其配置类的模块中导入模型。

在弃用期之后,Django将执行版本1.9的这些要求。

Subclassing AppCommand

AppCommand的子类现在必须实现handle_app_config()方法,而不是handle_app()此方法接收AppConfig实例,而不是模型模块。

Introspecting applications

由于INSTALLED_APPS现在还支持应用程序模块之外的应用程序配置类,因此您应该查看直接访问此设置的代码,并改为使用应用程序注册表(django.apps.apps)。

应用注册表保留了旧应用缓存的一些功能。即使应用缓存是专用API,过时的方法和参数也会通过标准弃用路径删除,但以下会立即生效的更改除外:

  • get_model提高LookupError,而不是在找不到模型时返回None
  • The only_installed argument of get_model and get_models no longer exists, nor does the seed_cache argument of get_model.

Management commands and order of INSTALLED_APPS

当多个应用程序提供具有相同名称的管理命令时,Django从INSTALLED_APPS中首先应用程序加载命令。以前的版本从最后运行的应用程序加载命令。

这使得管理命令的发现符合依赖于INSTALLED_APPS顺序的Django的其他部分,例如静态文件,模板和翻译。

ValidationError constructor and internal storage

ValidationError构造函数的行为在接收到错误的容器作为参数时已更改。a listErrorList):

  • 它将它找到的任何字符串转换为ValidationError的实例,然后将它们添加到其内部存储。
  • 它不存储给定的容器,而是将其内容复制到其自己的内部存储;之前容器本身已添加到ValidationError实例并用作内部存储。

这意味着如果您访问ValidationError内部存储器,例如error_listerror_dict;或update_error_dict()的返回值,您可能会在之前找到的字符串中找到ValidationError的实例。

Also if you directly assigned the return value of update_error_dict() to Form._errors you may inadvertently add list instances where ErrorList instances are expected. 这是一个问题,因为与简单的列表不同,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)

If you need both Django <= 1.6 and 1.7 compatibility you can’t use Form.add_error() since it wasn’t available before Django 1.7, but you can use the following workaround to convert any list into 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)

Behavior of LocMemCache regarding pickle errors

Django的以前版本中存在不一致,涉及不同的缓存后端如何处理pickle错误。django.core.cache.backends.locmem.LocMemCache用于在发生此类错误时失败,这与其他后端不一致,并导致特定于缓存的错误。这已在Django 1.7中修复,有关详细信息,请参阅#21200

Cache keys are now generated from the request’s absolute URL

先前版本的Django使用请求的路径和查询字符串生成缓存密钥,但不生成方案或主机。如果Django应用程序服务多个子域或域,缓存键可能会冲突。在Django 1.7中,缓存键因请求的绝对URL而异,包括scheme,host,path和query字符串。例如,缓存键的网址部分现在是从http://www.example.com/path/to/?key=val而不是/path/to/?key=val由Django 1.7生成的缓存键将与由旧版本的Django生成的键不同。升级到Django 1.7后,对任何先前缓存的URL的第一个请求将是缓存未命中。

Passing None to Manager.db_manager()

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

pytz may be required

如果您的项目在1970年之前或2037年之后处理数据时间,并且Django遇到ValueError时,您将不得不安装pytz如果您使用Django的时区相关日期格式或django.contrib.syndication,您可能会受此问题的影响。

Admin login redirection strategy

历史上,Django管理网站将未经授权或未经身份验证的用户的请求直接传递到登录视图,而没有HTTP重定向。In Django 1.7, this behavior changed to conform to a more traditional workflow where any unauthorized request to an admin page will be redirected (by HTTP status code 302) to the login page, with the next parameter set to the referring path. 成功登录后,用户将被重定向到那里。

还请注意,管理员登录表单已更新为不包含this_is_the_login_form字段(现在未使用),并且ValidationError代码已设置为更常规的invalid_login

select_for_update() requires a transaction

历史上,使用select_for_update()的查询可以在事务之外的自动提交模式下执行。在Django 1.6之前,Django的自动事务模式允许使用它来锁定记录,直到下一个写操作。Django 1.6引入了数据库级自动提交;从那时起,在这种上下文中的执行会影响select_for_update()的效果。因此,现在假定它是一个错误并引发一个异常。

进行此更改是因为此类错误可能是由于包含预期全局事务的应用程序(例如,ATOMIC_REQUESTS设置为True)或Django的旧自动提交行为,在没有它们的项目中运行;并且此外,这样的错误可以表现为数据腐败错误。它也是在Django 1.6.3。

如果在作为TransactionTestCase而不是TestCase的子类的测试类中使用select_for_update(),则此更改可能会导致测试失败。

Contrib middleware removed from default MIDDLEWARE_CLASSES

使用不属于INSTALLED_APPS设置的应用中的模型,已弃用app-loading refactor这暴露了全局默认值(django.conf.global_settings)中默认的INSTALLED_APPSMIDDLEWARE_CLASSES之间的不兼容性。要使这些设置保持同步并防止在以最少设置测试可重复使用的应用时发生弃用警告,请移除SessionMiddlewareAuthenticationMiddlewareMessageMiddleware从默认值。这些类仍将包含在由startproject生成的默认设置中。大多数项目不会受到此更改的影响,但如果您之前未在项目设置中声明MIDDLEWARE_CLASSES并依赖于全局默认值,则应确保新默认值与项目的需求一致。您还应该检查直接访问django.conf.global_settings.MIDDLEWARE_CLASSES的任何代码。

Miscellaneous

  • django.core.files.uploadhandler.FileUploadHandler.new_file()方法现在传递了另一个content_type_extra参数。如果您有实现new_file()的自定义FileUploadHandler,请确保接受此新参数。

  • ModelFormSets no longer delete instances when save(commit=False) is called. 有关如何手动删除已删除表单中的对象的说明,请参阅can_delete

  • 加载空夹具会发出RuntimeWarning,而不是提高CommandError

  • django.contrib.staticfiles.views.serve() will now raise an Http404 exception instead of ImproperlyConfigured when DEBUG is False. 此更改不需要有条件地将视图添加到根URLconf,这反过来使得可以安全地按名称进行反转。它还消除了访问者通过请求不存在或尚未收集的静态文件来生成假的HTTP 500错误的能力。

  • django.db.models.Model.__eq__()方法现在定义为,当主键匹配时,代理模型的实例及其基本模型被认为是相等的。以前只有完全相同的类的实例被认为在主键匹配上是相等的。

  • django.db.models.Model.__eq__()方法已更改,使得两个不带主键值的Model实例不会被视为相等(除非它们相同实例)。

  • 当在没有主键值的实例上调用时,django.db.models.Model.__hash__()方法现在将调用TypeError这是为了避免容器中的可变的__hash__值。

  • 现在将使用AUTOINCREMENT选项创建SQLite数据库中的AutoField列,这将确保单调递增。这将导致主键编号行为在SQLite上更改,与大多数其他SQL数据库一致。这将只适用于新创建的表。如果您有使用旧版本的Django创建的数据库,您将需要迁移它以利用此功能。例如,您可以执行以下操作:

    1. 使用dumpdata保存数据。
    2. 重命名现有数据库文件(将其保留为备份)。
    3. 运行migrate创建更新的模式。
    4. 使用loaddata导入您在(1)中导出的灯具。
  • django.contrib.auth.models.AbstractUser不再定义get_absolute_url()方法。旧定义会传回“/ users /%s /” urlquote(self.username)因为应用程序可能或可能不会在urlpatterns中定义此类网址。在您自己的自定义用户对象上定义get_absolute_url()方法,或者如果您希望为用户提供网址,请使用ABSOLUTE_URL_OVERRIDES

  • django.test.LiveServerTestCase类的静态资产提供功能已经过简化:现在,只有在运行测试时,它才能提供已存在于STATIC_ROOT中的内容。The ability to transparently serve all the static assets (similarly to what one gets with DEBUG = True at development-time) has been moved to a new class that lives in the staticfiles application (the one actually in charge of such feature): django.contrib.staticfiles.testing.StaticLiveServerTestCase. 换句话说,LiveServerTestCase本身不太强大,但同时具有较少的魔法。

    这背后的理由是去除非contrib代码对contrib应用程序的依赖。

  • 旧的高速缓存URI语法(例如,"locmem://")不再受支持。它仍然工作,即使它没有记录或正式支持。如果您仍在使用它,请更新为当前的CACHES语法。

  • 在继承的情况下,Form字段的默认顺序已更改为遵循正常的Python MRO。现在通过反向迭代MRO来发现字段,最后一个类是最后一个。如果您在父类Form上在当前类上定义字段时依赖于默认字段顺序,则此操作仅影响您。

  • SelectDateWidgetrequired参数已删除。此小部件现在与其他小部件一样遵守表单字段的is_required属性。

  • Widget.is_hidden现在是只读属性,通过查看是否存在input_type == 隐藏“

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

  • GeoDjango放弃了对GEOS的支持

  • 数据库后端的init_connection_state方法现在以自动提交模式执行(除非将AUTOCOMMIT设置为False)。

  • django.db.backends.BaseDatabaseFeatures.allows_primary_key_0属性已重命名为allows_auto_pk_0,以更好地描述它。对于Django中包含的所有数据库后端,它True,除了MySQL允许主键值为0。它仅禁止值为0的自动增量主键。

  • 父模型中定义的阴影模型字段已被禁止,因为这会在预期的模型行为中产生歧义。此外,模型继承层次结构中的冲突字段会导致系统检查错误。例如,如果使用多继承,则需要在父模型上定义自定义主键字段,否则默认的id字段会冲突。有关详细信息,请参阅Multiple inheritance

  • 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数据库。这是为了代替以前连接到实际的非测试数据库的行为。

  • 作为System check frameworkfields, models, and model managers的一部分,都实现了向检查框架注册的check()方法。如果您在其中一个对象上有一个名为check()的现有方法,则需要重命名它。

  • 如上所述,在“次要特性”的“缓存”部分中,将CACHES设置的TIMEOUT参数定义为None键为“未到期”。以前,使用内存缓存后端,0TIMEOUT将设置非过期密钥,但这与设置和过期(即,没有缓存)设置(“键”, “值”, timeout = 0)的行为。如果您想要未过期的键,请更新您的设置,使用None而不是0,因为后者现在还在设置中指定设置和到期。

  • sql*管理命令现在遵守DATABASE_ROUTERSallow_migrate()方法。如果模型已同步到非默认数据库,请使用--database标志为这些模型获取SQL(以前它们将始终包含在输出中)。

  • 当输入无效的UTF-8时,解码来自URL的查询字符串现在将返回到ISO-8859-1编码。

  • 通过向默认项目模板(仅限于1.7.2版)添加SessionAuthenticationMiddleware,必须在使用runserver访问页面之前创建数据库。

Features deprecated in 1.7

django.core.cache.get_cache

django.core.cache.get_cache()已被django.core.cache.caches取代。

django.utils.dictconfig/django.utils.importlib

django.utils.dictconfigdjango.utils.importlib分别是logging.configimportlib的副本Python之前的2.7版本。它们已被弃用。

django.utils.module_loading.import_by_path

当前import_by_path()函数捕获AttributeErrorImportErrorValueError异常,并重新提出ImproperlyConfigured这种异常掩蔽使得它不必要地很难诊断循环导入问题,因为它使它看起来像问题来自Django内部。它已被弃用,赞成import_string()

django.utils.tzinfo

django.utils.tzinfo提供了两个tzinfo子类,LocalTimezoneFixedOffset对于由django.utils.timezonedjango.utils.timezone.get_default_timezone()django.utils.timezone.get_fixed_timezone()

django.utils.unittest

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

django.utils.datastructures.SortedDict

由于在Python 2.7中将OrderedDict添加到标准库中,因此不再需要使用SortedDict,因此已被弃用。

SortedDictinsert()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']
)

Custom SQL location for models package

Previously, if models were organized in a package (myapp/models/) rather than simply myapp/models.py, Django would look for initial SQL data in myapp/models/sql/. 这个bug已经修复,Django将搜索myapp/sql/修复此问题后,添加了迁移,其中弃用初始SQL数据。因此,虽然此更改仍然存在,但不推荐使用,因为整个功能部件将在Django 1.9中删除。

Reorganization of django.contrib.sites

django.contrib.sites在不在INSTALLED_APPS中时提供缩减的​​功能。应用程序加载重构在这种情况下添加了一些约束。因此,两个对象已移动,旧位置已弃用:

declared_fieldsets attribute on ModelAdmin

ModelAdmin.declared_fieldsets已被弃用。尽管是一个私有API,它将通过一个常规的弃用路径。此属性主要由绕过ModelAdmin.get_fieldsets()的方法使用,但这被视为一个错误并已解决。

Reorganization of django.contrib.contenttypes

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

syncdb

已弃用syncdb命令以支持新的migrate命令。migrate使用与syncdb相同的参数加上几个,因此可以安全地更改您正在调用的名称,没有别的。

util modules renamed to 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

get_formsets method on ModelAdmin

为了更好地处理在ModelAdmin上选择性显示内联的情况,ModelAdmin.get_formsets已被弃用支持新的get_formsets_with_inlines()

BaseMemcachedCache._get_memcache_timeout method

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

Natural key serialization options

dumpdata--natural-n选项已被弃用。请改用--natural-foreign

类似地,serializers.serialize()use_natural_keys参数已被弃用。请改用use_natural_foreign_keys

Merging of POST and GET arguments into WSGIRequest.REQUEST

已经强烈建议您使用GETPOST而不是REQUEST,因为前者更加明确。属性REQUEST已弃用,将在Django 1.9中移除。

django.utils.datastructures.MergeDict class

MergeDict exists primarily to support merging POST and GET arguments into a REQUEST property on WSGIRequest. 要合并字典,请改用dict.update()MergeDict已弃用,将在Django 1.9中删除。

Language codes zh-cn, zh-tw and fy-nl

目前使用的简体中文zh-cn,繁体中文zh-tw和(西部)Frysian fy-nl的语言代码已弃用,分别替换为语言代码zh-hanszh-hantfy如果您使用这些语言代码,则应重命名区域设置目录并更新您的设置以反映这些更改。已弃用的语言代码将在Django 1.9中删除。

django.utils.functional.memoize function

函数memoize已废弃,应由functools.lru_cache装饰器(可从Python 3.2开始)替换。

Django ships a backport of this decorator for older Python versions and it’s available at django.utils.lru_cache.lru_cache. 已弃用的函数将在Django 1.9中删除。

Geo Sitemaps

Google已停止支援「地理Sitemap」格式。因此,Django对Geo Sitemap的支持已弃用,将在Django 1.8中删除。

Passing callable arguments to queryset methods

查询集的可调参数是不可靠的未记录的功能。它已被弃用,将在Django 1.9中删除。

ADMIN_FOR setting

作为admindocs的一部分的ADMIN_FOR功能已删除。您可以在方便时从配置中删除该设置。

SplitDateTimeWidget with DateTimeField

DateTimeField中的SplitDateTimeWidget支持已弃用,请改用SplitDateTimeWidgetSplitDateTimeField

validate

validate命令已弃用,支持check命令。

django.core.management.BaseCommand

requires_model_validation is deprecated in favor of a new requires_system_checks flag. 如果后一个标志丢失,则使用前一个标志的值。定义requires_system_checksrequires_model_validation会导致错误。

check()方法替换了旧的validate()方法。

ModelAdmin validators

不推荐使用ModelAdmin.validator_classdefault_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()的实现。

Loading ssi and url template tags from future library

Django 1.3 introduced {% load ssi from future %} and {% load url from future %} syntax for forward compatibility of the ssi and url template tags. 此语法现已弃用,将在Django 1.9中删除。You can simply remove the {% load ... from future %} tags.

django.utils.text.javascript_quote

javascript_quote()django.utils.text中存在的未记录的函数。它在内部在javascript_catalog view中使用,其实现已更改为使用json.dumps()如果您依靠此函数从不受信任的字符串提供安全输出,则应使用django.utils.html.escapejsescapejs模板过滤器。如果您需要的是生成有效的JavaScript字符串,则可以使用json.dumps()

fix_ampersands utils method and template filter

django.utils.html.fix_ampersands方法和fix_ampersands模板过滤器已弃用,因为&符号的转义已由Django的标准HTML转义功能处理。将此与fix_ampersands结合将导致双重转义,或者,如果输出被假定为安全的,则存在引入XSS漏洞的风险。除了fix_ampersandsdjango.utils.html.clean_html已被弃用,这是一个未记录的函数,调用fix_ampersands由于这是加速淘汰,因此在Django 1.8中将删除fix_ampersandsclean_html

Reorganization of database test settings

具有TEST_前缀的所有数据库设置已被弃用,以利用数据库设置中TEST字典中的条目。旧的设置将被支持,直到Django 1.9。为了向后兼容旧版本的Django,您可以定义两个版本的设置,只要它们匹配。

FastCGI support

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

Moved objects in contrib.sites

在应用程序加载重构器之后,需要移动django.contrib.sites.models中的两个对象,因为它们必须可用,而不导入django.contrib.sites.models django.contrib.sites未安装。django.contrib.sites.shortcuts导入django.contrib.sites.requestsget_current_site()RequestSite旧的导入位置将工作,直到Django 1.9。

django.forms.forms.get_declared_fields()

Django不再在内部使用这个功能。即使它是一个私有API,它会经历正常的淘汰循环。

Private Query Lookup APIs

专用API django.db.models.sql.where.WhereNode.make_atom()django.db.models.sql.where.Constraint已弃用,支持新的custom lookups API

Features removed in 1.7

这些功能已到达其deprecation cycle的末尾,因此已在Django 1.7中移除(有关详情,请参阅deprecation timeline):