Skip to main content

Django 1.9发行说明

2015年12月1日

欢迎使用Django 1.9!

这些发行说明涵盖了 新功能,以及从Django 1.8或更早版本升级时需要注意的一些 向后不兼容的更改。我们的 dropped some features 已达到其淘汰期结束,我们有 开始折旧过程的一些功能

如果您要更新现有项目,请参阅 将Django升级到较新版本 指南。

Python兼容性

Django 1.9需要Python 2.7,3.4或3.5。我们 强烈推荐 只是正式支持每个系列的最新版本。

Django 1.8系列是最后一个支持Python 3.2和3.3的。

Django 1.9中的新功能

在事务提交后执行操作

新的 on_commit() 挂钩允许在数据库事务成功提交后执行操作。这对于发送通知电子邮件,创建排队任务或使缓存无效等任务非常有用。

来自 django-transaction-hooks 包的此功能已集成到Django中。

密码验证

Django现在提供密码验证,以帮助防止用户使用弱密码。验证集成在所包含的密码更改和重置表单中,并且易于集成到任何其他代码中。验证由一个或多个验证器执行,在新的 AUTH_PASSWORD_VALIDATORS 设置中配置。

Django中包含四个验证程序,可以强制实施最小长度,将密码与用户的属性(例如其名称)进行比较,确保密码不是完全数字的,或者检查包含的常用密码列表。您可以组合多个验证器,并且一些验证器具有自定义配置选项。例如,您可以选择提供常用密码的自定义列表。每个验证器提供帮助文本,以向用户解释其要求。

默认情况下,不会执行验证,并且接受所有密码,因此如果您未设置 AUTH_PASSWORD_VALIDATORS,则不会看到任何更改。在使用默认 startproject 模板创建的新项目中,启用一组简单的验证器。要在包含的您的项目的身份验证表单中启用基本验证,您可以设置为例如:

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

有关详细信息,请参阅 密码验证

基于类的视图的权限混合

Django现在附带了mixin AccessMixinLoginRequiredMixinPermissionRequiredMixinUserPassesTestMixin,为基于类的视图提供 django.contrib.auth.decorators 的功能。这些混合组件已经从 django-braces 项目中获取或至少受到 django-braces 项目的启发。

虽然Django和 django-braces ‘实现之间有一些区别:

  • raise_exception 属性只能是 TrueFalse。不支持自定义例外或callable。

  • handle_no_permission() 方法不采用 request 参数。当前请求在 self.request 中可用。

  • UserPassesTestMixin 的自定义 test_func() 不采用 user 参数。当前用户在 self.request.user 中可用。

  • permission_required 属性支持需要满足以授予访问权限的字符串(定义一个权限)或字符串的列表/元组(定义多个权限)。

  • 新的 permission_denied_message 属性允许将消息传递给 PermissionDenied 异常。

contrib.admin 的新样式

管理员运动现代,平面设计与新的SVG图标,看起来完美的HiDPI屏幕上。它仍然为 YUI’s A-grade 浏览器提供全功能的体验。较旧的浏览器可能会遇到不同级别的正常降级。

并行运行测试

test 命令现在支持 --parallel 选项以在多个进程中并行运行项目的测试。

每个进程都有自己的数据库。您必须确保不同的测试用例不访问相同的资源。例如,接触文件系统的测试用例应该创建一个临时目录供自己使用。

默认情况下,为Django自己提供的测试套件启用此选项:

  • 操作系统支持它(除Windows之外的所有操作系统)

  • 数据库后端支持它(所有内置后端,但是Oracle)

次要功能

django.contrib.admin

  • 管理视图现在具有 model_adminadmin_site 属性。

  • 管理更改视图的URL已更改(默认情况下位于 /admin/<app>/<model>/<pk>/,现在位于 /admin/<app>/<model>/<pk>/change/)。这不应影响您的应用程序,除非您有硬编码的管理员网址。在这种情况下,请用 反转管理URL 替换这些链接。请注意,旧网址仍会重定向到新网址以实现向后兼容性,但可能会在以后的版本中删除。

  • 添加了 ModelAdmin.get_list_select_related() 以允许根据请求更改在管理员的更改列表查询中使用的 select_related() 值。

  • available_apps 上下文变量(其列出了当前用户的可用应用程序)已添加到 AdminSite.each_context() 方法。

  • 添加了 AdminSite.empty_value_displayModelAdmin.empty_value_display 以覆盖在管理更改列表中显示的空值。您还可以自定义每个字段的值。

  • 在更改表单页面上添加了jQuery事件 当添加或删除内联表单时

  • 时间选择器小部件包括一个“6 p.m”选项,用于每6小时具有预定义选项的一致性。

  • JavaScript slug生成现在支持罗马尼亚字符。

django.contrib.admindocs

  • admindocs 的模型部分现在还描述了接受参数的方法,而不是忽略它们。

django.contrib.auth

  • PBKDF2密码hasher的默认迭代计数已增加了20%。此向后兼容的更改不会影响已将 django.contrib.auth.hashers.PBKDF2PasswordHasher 子类化为更改默认值的用户。

  • BCryptSHA256PasswordHasher 现在将更新密码,如果其 rounds 属性更改。

  • AbstractBaseUserBaseUserManager 被移动到一个新的 django.contrib.auth.base_user 模块,使它们可以导入,而不包括 INSTALLED_APPS 中的 django.contrib.auth (这样做在老版本中提出了弃用警告,并且在Django 1.9中不再支持)。

  • permission_required() 的permission参数接受所有种类的迭代,不仅仅是列表和元组。

  • 新的 PersistentRemoteUserMiddleware 使得可以使用 REMOTE_USER 来进行设置,其中头部仅填充在登录页面上而不是会话中的每个请求。

  • password_reset() 视图接受 extra_email_context 参数。

django.contrib.contenttypes

django.contrib.gis

  • 所有 GeoQuerySet 方法已被弃用,并被 等效数据库函数 取代。一旦遗留的方法在代码中被替换,您甚至应该能够从支持GIS的类中删除特殊的 GeoManager

  • GDAL接口现在支持从原始数据实例化基于文件和内存的 GDALRaster对象。添加了用于栅格属性(如投影或像素值)的设置器。

  • 对于PostGIS用户,新的 RasterField 允许 存储GDALRaster对象。它支持在保存模型时自动创建空间索引和重新投影。它还不支持空间查询。

  • 新的 GDALRaster.warp() 方法允许通过指定目标光栅属性(例如原点,宽度,高度或像素大小(等等))来变形光栅。

  • 新的 GDALRaster.transform() 方法允许通过指定目标 srid 将栅格变换到不同的空间参考系。

  • 新的 GeoIP2 类允许使用MaxMind的GeoLite2数据库,其中包括对IPv6地址的支持。

  • 窗口小部件中包含的默认OpenLayers库版本已从2.13更新到2.13.1。

django.contrib.postgres

django.contrib.sessions

  • 重构了 dbcached_db 后端的会话模型和 SessionStore 类,以允许自定义数据库会话后端构建它们。详情请参阅 扩展数据库支持的会话引擎

django.contrib.sites

  • get_current_site() 现在处理 request.get_host() 返回 domain:port 的情况,例如。 example.com:80。如果查找失败,因为主机与数据库中的记录不匹配,并且主机具有端口,则端口将被剥离,并且仅使用域部件重试查找。

django.contrib.syndication

  • 已添加对每个Feed项目支持多个机箱。如果在RSS订阅源上定义了多个机箱,则会出现异常,因为RSS Feed与Atom订阅源不同,不支持每个订阅源项目使用多个机箱。

缓存

  • django.core.cache.backends.base.BaseCache 现在有一个 get_or_set() 方法。

  • django.views.decorators.cache.never_cache() 现在发送更有说服力的头(添加 no-cache, no-store, must-revalidateCache-Control),以更好地防止缓存。这也添加在Django 1.8.8中。

CSRF

数据库后端

  • PostgreSQL后端(django.db.backends.postgresql_psycopg2)也可以作为 django.db.backends.postgresql。旧名称将继续可用于向后兼容。

文件存储

形式

  • ModelForm 接受新的 Meta 选项 field_classes 以自定义字段的类型。有关详细信息,请参阅 覆盖默认字段

  • 现在可以使用 field_order 属性,field_order 构造函数参数或 order_fields() 方法指定表单字段的呈现顺序。

  • 可以在表单类中指定表单前缀,而不仅仅是在实例化表单时。有关详细信息,请参阅 表单的前缀

  • 您现在可以将 指定关键字参数 传递给表单集中的表单的构造函数。

  • SlugField 现在接受一个 allow_unicode 参数,以允许slugs中的Unicode字符。

  • CharField 现在接受一个 strip 参数来剥离前导和尾随空格的输入数据。由于此默认为 True,这是与以前版本不同的行为。

  • 表单字段现在支持 disabled 参数,允许字段小部件显示为禁用浏览器。

  • 现在可以通过覆盖字段的 get_bound_field() 方法来自定义绑定字段。

通用视图

  • 使用 as_view() 生成的基于类的视图现在具有 view_classview_initkwargs 属性。

  • method_decorator() 现在可以与装饰器的列表或元组一起使用。它也可以用于 装饰类而不是方法

国际化

  • django.views.i18n.set_language() 视图现在正确重定向到 翻译的URL (如果可用)。

  • 如果在同一页面上使用不同配置多次使用,django.views.i18n.javascript_catalog() 视图现在可以正常工作。

  • django.utils.timezone.make_aware() 函数获得了 is_dst 参数,以帮助解决DST转换期间的模糊时间。

  • 您现在可以使用gettext支持的区域设置变体。这些通常用于可以用不同的脚本书写的语言,例如拉丁文和西里尔文(例如 be@latin)。

  • 添加了 django.views.i18n.json_catalog() 视图,以帮助在Django转换后构建自定义客户端i18n库。它返回包含翻译目录,格式设置和复数规则的JSON对象。

  • name_translated 属性添加到 get_language_info 模板标记返回的对象。还添加了相应的模板过滤器:language_name_translated

  • 您现在可以从项目的根目录运行 compilemessages,它将找到由 makemessages 创建的所有应用程序消息文件。

  • makemessages 现在每个locale目录调用xgettext一次,而不是每个可翻译文件调用一次。这加快了本地化构建。

  • blocktrans 支持使用 asvar 将其输出分配给变量。

  • 有两种新语言可供选择:哥伦比亚西班牙语和苏格兰盖尔语。

管理命令

  • 新的 sendtestemail 命令允许您发送测试电子邮件,以轻松确认通过Django发送的电子邮件是否正常工作。

  • 为了提高 sqlmigrate 生成的SQL代码的可读性,为每个迁移操作生成的SQL代码之前是操作的描述。

  • dumpdata 命令输出现在是确定性排序的。此外,当指定 --output 选项时,它还在终端中显示进度条。

  • createcachetable 命令现在有一个 --dry-run 标志打印出SQL而不是执行它。

  • startapp 命令创建 apps.py 文件。由于它不使用 default_app_config一个不鼓舞的API),您必须指定应用程序配置的路径,例如。 'polls.apps.PollsConfig',在 INSTALLED_APPS 中使用(而不仅仅是 'polls')。

  • 当使用PostgreSQL后端时,dbshell 命令可以使用设置文件中的密码连接到数据库(而不是手动输入)。

  • django 包可以作为脚本运行,即 python -m django,其将表现与 django-admin 相同。

  • 具有 --noinput 选项的管理命令现在也将 --no-input 作为该选项的别名。

迁移

  • 初始迁移现在标记有 initial = True 类属性,这允许 migrate --fake-initial 更容易地检测初始迁移。

  • 增加了对 functools.partialLazyObject 实例的序列化的支持。

  • 当在 MIGRATION_MODULES 中提供 None 作为值时,Django将会考虑应用程序而不进行迁移。

  • 应用迁移时,当以verbosity 2或更高级别运行迁移时显示的“渲染模型状态”步骤现在仅计算已应用的迁移的状态。正在应用的迁移的模型状态是根据需要生成的,从而大大减少了所需的内存量。

    但是,这种改进在不应用迁移时不可用,因此仍然需要预先计算和存储中间迁移状态。

    这种改进还要求Django不再支持混合迁移计划。混合计划包含一些迁移列表,其中一些正在应用,另一些正在应用。这从来没有正式支持,从来没有一个公开的API支持这种行为。

  • squashmigrations 命令现在支持指定迁移将被压缩的开始迁移。

楷模

  • QuerySet.bulk_create() 现在工作在代理模型上。

  • 数据库配置获得了一个 TIME_ZONE 选项,用于与在本地时间存储数据时间的数据库进行交互,并且当 USE_TZTrue 时不支持时区。

  • RelatedManager.set() 方法添加到由 ForeignKeyGenericForeignKeyManyToManyField 创建的相关管理器。

  • 反向外键上的 add() 方法现在具有 bulk 参数,以允许执行一个查询,而不考虑要添加的对象数量,而不是每个对象一个查询。

  • Model.delete() 添加了 keep_parents 参数,以允许只删除使用多表继承的模型中的子数据。

  • Model.delete()QuerySet.delete() 返回删除的对象数。

  • 添加了系统检查,以防止在同一型号上定义 Meta.orderingorder_with_respect_to

  • Date and time 查找可以与其他查找(例如 exactgtlt 等)链接。例如:Entry.objects.filter(pub_date__month__gt=6)

  • TimeField 现在支持所有数据库后端的时间查询(小时,分钟,秒)。支持除SQLite之外的后端,但在Django 1.7中没有记录。

  • 您可以指定 Avg 聚合的 output_field 参数,以便聚合非数字列(例如 DurationField)。

  • DateTimeField 添加了 date 查询,以允许仅通过日期部分查询字段。

  • 添加了 GreatestLeast 数据库功能。

  • 添加了 Now 数据库函数,它返回当前日期和时间。

  • Transform 现在是 Func() 的子类,它允许 Transform 在表达式的右手边使用,就像常规 Func 一样。这允许注册一些数据库函数,如 LengthLowerUpper 作为变换。

  • SlugField 现在接受一个 allow_unicode 参数,以允许slugs中的Unicode字符。

  • 添加了对 QuerySet.distinct() 中引用注释的支持。

  • connection.queries 在SQLite上显示具有替换参数的查询。

  • 现在可以在使用 save()create()bulk_create() 创建新模型实例时使用 查询表达式

请求和响应

  • 除非显式设置 HttpResponse.reason_phrase,否则现在由 HttpResponse.status_code 的当前值确定。修改 status_code 的值在构造函数之外也将修改 reason_phrase 的值。

  • 调试视图现在显示Python 3上的链接异常的详细信息。

  • 默认的40x错误视图现在接受第二个位置参数,触发视图的异常。

  • 查看错误处理程序现在支持 TemplateResponse,常用于基于类的视图。

  • render() 方法引发的异常现在传递到每个中间件的 process_exception() 方法。

  • 请求中间件现在可以将 HttpRequest.urlconf 设置为 None 以还原先前中间件所做的任何更改并返回到使用 ROOT_URLCONF

  • CommonMiddleware 中的 DISALLOWED_USER_AGENTS 检查现在引发 PermissionDenied 异常,而不是返回 HttpResponseForbidden,以便调用 handler403

  • 添加了 HttpRequest.get_port() 来获取请求的源端口。

  • JsonResponse 添加了 json_dumps_params 参数,以允许将关键字参数传递给用于生成响应的 json.dumps() 调用。

  • 当引荐者等于请求的网址时,BrokenLinkEmailsMiddleware 现在会忽略404。为了避免已经实现的空引用检查,一些Web机器人将引用程序设置为请求的URL。

模板

  • 使用 simple_tag() 帮助程序创建的模板标签现在可以使用 as 参数将结果存储在模板变量中。

  • 添加了 Context.setdefault() 方法。

  • 添加了 django.template 记录器,并包括以下消息:

    • 缺少上下文变量的 DEBUG 级消息。

    • 在调试模式关闭时在呈现 {% include %} 期间引发未捕获异常的 WARNING 级别消息(由于 {% include %} 使异常静默并返回空字符串,因此有帮助)。

  • firstof 模板标签支持使用“as”将输出存储在变量中。

  • Context.update() 现在可以用作上下文管理器。

  • Django模板加载器现在可以递归扩展模板。

  • 调试页面模板事后处理现在包括安装的每个引擎的输出。

  • 添加了自定义模板引擎的 调试页面集成

  • DjangoTemplates 后端通过模板 OPTIONS 显式地获得了注册库和内置函数的能力。

  • 改进 timesincetimeuntil 过滤器以在给定大的时间跨度时处理闰年。

  • include 标记现在在模板呈现期间缓存解析的模板对象,加速了在诸如for循环之类的地方的重用。

测试

  • 添加了 json() 方法来测试客户端响应,以JSON形式提供对响应主体的访问。

  • force_login() 方法添加到测试客户端。使用此方法来模拟登录到站点的用户的效果,同时跳过 login() 的身份验证和验证步骤。

网址

  • 现在,在URL模式中允许使用正则表达式回顾断言。

  • 现在可以使用所包含的模块或对象上的 app_name 属性来设置应用程序命名空间。它也可以通过传递一个2元组(<模式列表>,<应用程序命名空间>)作为 include() 的第一个参数来设置。

  • 系统检查已添加常见的网址格式错误。

验证器

1.9中的向后不兼容更改

警告

除了本节中概述的更改外,请务必查看 在1.9中删除的功能,了解已达到其淘汰期结束并因此已被移除的功能。如果您没有在特定功能的弃用时间轴内更新代码,则其移除可能会显示为向后不兼容的更改。

数据库后端API

  • 一些新的测试依赖于后端内省列默认值(将结果返回为 Field.default)的能力。如果您的后端没有实现此功能,您可以将 can_introspect_default 数据库功能设置为 False。您可能想要查看Django包含以供参考的后端实现(#24245)。

  • 在DB-API模块级别注册全局适配器或转换器,以处理作为查询参数传递的 datetime 值的时区信息,或者不支持在不支持时区的数据库上作为查询结果返回的 datetime 值的时区信息。它可能与其他库冲突。

    将时区添加到从数据库获取的 datetime 值的推荐方法是在 DatabaseOperations.get_db_converters() 中为 DateTimeField 注册转换器。

    needs_datetime_string_cast 数据库功能已删除。数据库后端设置它必须注册转换器,如上所述。

  • DatabaseOperations.value_to_db_<type>() 方法被重命名为 adapt_<type>field_value() 以镜像 convert_<type>field_value() 方法。

  • 要使用新的 date 查找,第三方数据库后端可能需要实现 DatabaseOperations.datetime_cast_date_sql() 方法。

  • 添加 DatabaseOperations.time_extract_sql() 方法。它调用现有的 date_extract_sql() 方法。此方法被SQLite后端覆盖,以向 TimeField 添加时间查找(小时,分钟,秒),并且可能需要第三方数据库后端。

  • DatabaseOperations.datetime_cast_sql() 方法(不要与上面提到的 DatabaseOperations.datetime_cast_date_sql() 混淆)已被删除。这种方法用于格式化日期早在1.0之前的Oracle,但没有被任何核心后端在几年中重写,并没有在Django的代码或测试中的任何地方调用。

  • 为了支持测试并行化,必须实现 DatabaseCreation._clone_test_db() 方法并设置 DatabaseFeatures.can_clone_databases = True。您可能需要调整 DatabaseCreation.get_test_db_clone_settings()

作为元组的默认设置现在是列表

django.conf.global_settings 中的默认设置是列表和元组的组合。所有以前是元组的设置现在都是列表。

模板装载器上的 is_usable 属性被删除

Django模板加载器以前需要定义 is_usable 属性。如果在模板设置中配置了加载程序,并且此属性为 False,则将忽略加载程序。在实践中,这只是由egg加载器用来检测是否安装setuptools。 is_usable 属性现在被删除,如果未安装setuptools,egg加载程序将在运行时失败。

基于文件系统的模板加载器捕获更具体的异常

当使用 filesystem.Loaderapp_directories.Loader 模板加载器时,如果模板源存在但不可读,Django的早期版本会引发 TemplateDoesNotExist 错误。这可能发生在许多情况下,例如,如果Django没有权限打开文件,或者如果模板源是一个目录。现在,Django只有在模板源不存在时才会忽略异常。所有其他情况导致原始 IOError 提高。

HTTP重定向不再强制为绝对URI

相对重定向不再转换为绝对URI。 RFC 2616 要求重定向响应中的 Location 头是绝对URI,但它已被 RFC 7231 取代,允许 Location 中的相对URI,识别用户代理的实际做法,几乎所有用户代理都支持它们。

因此,传递给 assertRedirects 的预期URL通常不再包括URL的方案和域部分。例如,self.assertRedirects(response, 'http://testserver/some-url/') 应该被 self.assertRedirects(response, '/some-url/') 替换(当然,除非重定向特别包含绝对URL)。

在极少数情况下,您需要旧的行为(用 mod_scgi 的旧版本发现,它将相对重定向解释为“内部重定向”),您可以通过编写自定义中间件:

class LocationHeaderFix(object):
    def process_response(self, request, response):
        if 'Location' in response:
            response['Location'] = request.build_absolute_uri(response['Location'])
        return response

删除对PostgreSQL 9.0的支持

PostgreSQL 9.0的上游支持于2015年9月结束。因此,Django 1.9将9.1设置为它正式支持的最低PostgreSQL版本。

删除对Oracle 11.1的支持

对Oracle 11.1的上游支持于2015年8月结束。因此,Django 1.9将11.2作为其正式支持的最低Oracle版本。

删除模板 LoaderOriginStringOrigin

在以前的Django版本中,当模板引擎以debug作为 True 初始化时,django.template.loader.LoaderOrigindjango.template.base.StringOrigin 的实例被设置为模板对象上的origin属性。这些类已经合并到 Origin 中,现在总是设置,而不管引擎调试设置。对于最小级别的向后兼容性,旧类名将保留为新 Origin 类的别名,直到Django 2.0。

更改默认日志记录配置

为了更容易编写自定义日志记录配置,Django的默认日志配置不再定义 django.requestdjango.security 日志记录器。相反,它定义了一个单一的 django 记录器,在 INFO 级别过滤,有两个处理程序:

  • console:在 INFO 级别滤波,仅在 DEBUG=True 时有效。

  • mail_admins:在 ERROR 级别滤波,仅在 DEBUG=False 时有效。

如果你不重写Django的默认日志记录,你应该看到行为的最小变化,但是你可能会看到一些新的日志记录到 runserver 控制台,例如。

如果你正在重写Django的默认日志记录,你应该检查看看你的配置如何与新的默认值合并。

错误报告中的 HttpRequest 详细信息

每次在调试页面的HTML版本中出现堆栈帧变量和错误电子邮件时,显示 HttpRequest 的全部详细信息是多余的。因此,HTTP请求现在将显示与其他变量(repr(request))相同的标准表示。结果,去除了 ExceptionReporterFilter.get_request_repr() 方法和未记录的 django.http.build_request_repr() 功能。

修改了电子邮件的文本版本的内容,以提供与AJAX请求的情况相同的结构的跟踪。回溯细节由 ExceptionReporter.get_traceback_text() 方法呈现。

删除用于数据时间的时区感知全局适配器和转换器

Django不再注册全局适配器和转换器来管理作为查询参数发送到数据库的 datetime 值的时区信息或在查询结果中从数据库读取。此更改会影响满足以下所有条件的项目:

  • USE_TZ 设置为 True

  • 数据库是SQLite,MySQL,Oracle或不支持时区的第三方数据库。毫无疑问,你可以检查 connection.features.supports_timezones 的值。

  • 该代码查询ORM之外的数据库,通常使用 cursor.execute(sql, params)

如果你知道 datetime 参数到这样的查询,你应该把它们变成天真的数据时间在UTC:

from django.utils import timezone
param = timezone.make_naive(param, timezone.utc)

如果您没有这样做,转换将像早期版本(使用deprecation警告),直到Django 1.11。 Django 2.0不会执行任何转换,这可能会导致数据损坏。

如果你从结果中读取 datetime 值,他们将是幼稚的,而不是意识。您可以如下补偿:

from django.utils import timezone
value = timezone.make_aware(value, timezone.utc)

如果您通过ORM查询数据库,即使您使用的是 raw() 查询,也不需要这样做。 ORM负责管理时区信息。

配置模板时导入模板标记模块

DjangoTemplates 后端现在在实例化时对安装的模板标记模块执行发现。此更新使得可以在定义 DjangoTemplates 后端时通过 OPTIONS'libraries' 键显式提供库。模板标记模块中的导入或语法错误现在在实例化时失败,而不是首次编译具有 {% load %} 标记的模板时失败。

django.template.base.add_to_builtins() 被删除

尽管它是一个私有API,项目通常使用 add_to_builtins() 来使模板标签和过滤器可用,而不使用 {% load %} 标签。此API已正式化。现在,在定义 DjangoTemplates 后端时,项目应通过 OPTIONS'builtins' 键定义内置库。

simple_tag 现在将标签输出包装在 conditional_escape

一般来说,模板标签不会自动转义其内容,这种行为是 记录。对于像 inclusion_tag 这样的标签,这不是问题,因为包含的模板将执行自动转义。对于 assignment_tag,当输出在模板中用作变量时将被转义。

然而,对于 simple_tag 的预期用例,很容易导致不正确的HTML和可能的XSS攻击。例如:

@register.simple_tag(takes_context=True)
def greeting(context):
    return "Hello {0}!".format(context['request'].user.first_name)

在旧版本的Django中,这将是一个XSS问题,因为 user.first_name 没有转义。

在Django 1.9中,这是固定的:如果模板上下文具有 autoescape=True 集(默认),则 simple_tag 将使用 conditional_escape() 包装标签函数的输出。

要修复您的 simple_tag,最好应用以下做法:

  • 任何生成HTML的代码都应该使用模板系统或 format_html()

  • 如果 simple_tag 的输出需要转义,请使用 escape()conditional_escape()

  • 如果您绝对确定要从受信任来源(例如,存储由管理员输入的HTML的CMS字段)输出HTML,则可以使用 mark_safe() 将其标记为HTML。

遵循这些规则的标签将是正确和安全的,无论它们是在Django 1.9+或更早版本上运行。

Paginator.page_range

Paginator.page_range 现在是一个迭代器而不是列表。

在1.8之前的版本的Django中,Paginator.page_range 在Python 2中返回了 list,在Python 3中返回了一个 range。Django 1.8始终返回一个列表,但迭代器更高效。

依赖于 list 特定功能(例如索引)的现有代码可以通过使用 list() 将迭代器转换为 list 来移植。

隐式 QuerySet __in 查找已删除

在早期版本中,查询如:

Model.objects.filter(related_id=RelatedModel.objects.all())

将隐式转换为:

Model.objects.filter(related_id__in=RelatedModel.objects.all())

导致像 "related_id IN (SELECT id FROM ...)" 的SQL。

这个隐式 __in 不再发生,所以“IN”SQL现在是“=”,如果子查询返回多个结果,至少有一些数据库会抛出一个错误。

contrib.admin 浏览器支持

管理员不再支持Internet Explorer 8及以下版本,因为这些浏览器已到达使用期限。

支持Internet Explorer 6和7的CSS和图像已删除。 PNG和GIF图标已被替换为SVG图标,Internet Explorer 8和更早版本不支持。

嵌入在管理中的jQuery库已从版本1.11.2升级到2.1.4。 jQuery 2.x具有与jQuery 1.x相同的API,但不支持Internet Explorer 6,7或8,允许更好的性能和更小的文件大小。如果你需要支持IE8并且还必须使用最新版本的Django,你可以通过创建一个带有这个结构的Django应用程序来覆盖你自己的jQuery的管理员副本:

app/static/admin/js/vendor/
    jquery.js
    jquery.min.js

SyntaxError 时安装Django setuptools 5.5.x

当使用setuptools 5.5.x安装Django 1.9或1.9.1时,你会看到:

Compiling django/conf/app_template/apps.py ...
  File "django/conf/app_template/apps.py", line 4
    class {{ camel_case_app_name }}Config(AppConfig):
          ^
SyntaxError: invalid syntax

Compiling django/conf/app_template/models.py ...
  File "django/conf/app_template/models.py", line 1
    {{ unicode_literals }}from django.db import models
                             ^
SyntaxError: invalid syntax

它可以安全地忽略这些错误(Django仍然会安装很好),但你可以通过将setuptools升级到更新的版本来避免它们。如果你使用pip,你可以升级pip使用 pip install -U pip,这也将升级setuptools。这在以后的Django版本中解决,如 Django 1.9.2发行说明 中所述。

  • contrib.admin 中的jQuery静态文件已移至 vendor/jquery 子目录中。

  • 在管理更改列表 list_display 单元格中为空列显示的文本已从 (None) (或其转换的等价物)更改为 - (短划线)。

  • django.http.responses.REASON_PHRASESdjango.core.handlers.wsgi.STATUS_CODE_TEXT 已删除。使用Python的stdlib代替:http.client.responses 用于Python 3,httplib.responses 用于Python 2。

  • ValuesQuerySetValuesListQuerySet 已删除。

  • admin/base.html 模板不再设置 window.__admin_media_prefix__window.__admin_utc_offset__。使用该值构造绝对URL的JavaScript中的图像引用已被移动到CSS,以便于定制。 UTC偏移存储在 <body> 标签的数据属性上。

  • CommaSeparatedIntegerField 验证已被改进为禁止像 ','',1''1,,2' 的值。

  • 将表单初始化从 ProcessFormView.get() 方法移动到新的 FormMixin.get_context_data() 方法。如果您在不调用 super() 的情况下覆盖了 get_context_data() 方法,则这可能向后不兼容。

  • 支持PostGIS 1.5已经删除。

  • django.contrib.sites.models.Site.domain 字段更改为 unique

  • 为了实施测试隔离,默认情况下不允许在 SimpleTestCase 测试中进行数据库查询。您可以通过在测试类上将 allow_database_queries 类属性设置为 True 来禁用此行为。

  • 在嵌套命名空间的情况下,ResolverMatch.app_name 已更改为包含完整的命名空间路径。为了与 ResolverMatch.namespace 一致,空值现在是空字符串,而不是 None

  • 对于安全加固,会话密钥必须至少为8个字符。

  • 私有函数 django.utils.functional.total_ordering() 已删除。它包含了在2.7.3以前的Python版本中的 functools.total_ordering() 错误的解决方法。

  • 用于输出其接收的任何字符的XML序列化(通过 dumpdata 或聚合框架)。现在,如果要序列化的内容包含XML 1.0标准中不允许的任何控制字符,则序列化将失败,并出现 ValueError

  • 默认情况下,CharField 现在删除前导和尾随空格的输入。这可以通过将新的 strip 参数设置为 False 来禁用。

  • 转换的模板文本,并使用两个或多个连续的百分号,例如 "%%",在运行 makemessages 之后可能具有新的 msgid (很可能翻译将被标记为模糊)。新的 msgid 将被标记为 "#, python-format"

  • 如果既没有设置 request.current_app 也没有设置 Context.current_app,则 url 模板标签现在将使用当前请求的命名空间。如果不想使用命名空间提示,请将 request.current_app 设置为 None

  • SILENCED_SYSTEM_CHECKS 设置现在静默所有级别的消息。以前,将 ERROR 级别或更高级别的消息打印到控制台。

  • FlatPage.enable_comments 字段从应用程序未使用的 FlatPageAdmin 中删除。如果您的项目或第三方应用程序使用它,创建自定义ModelAdmin 将其添加回来。

  • setup_databases() 的返回值和 teardown_databases() 的第一个参数已更改。他们曾经是 (old_names, mirrors) 元组。现在他们只是第一个项目,old_names

  • 默认情况下,LiveServerTestCase 尝试在8081-8179范围中查找可用端口,而不是仅尝试端口8081。

  • 系统检查 ModelAdmin 现在检查实例而不是类。

  • 由于性能原因,用于应用混合迁移计划的专用API已被删除。混合计划包含一些迁移列表,其中一些正在应用,另一些正在应用。

  • django.db.models.fields.related 中的相关模型对象描述符类(私有API)从 related 模块移动到 related_descriptors,并重命名如下:

    • ReverseSingleRelatedObjectDescriptorForwardManyToOneDescriptor

    • SingleRelatedObjectDescriptorReverseOneToOneDescriptor

    • ForeignRelatedObjectsDescriptorReverseManyToOneDescriptor

    • ManyRelatedObjectsDescriptorManyToManyDescriptor

  • 如果实现自定义 handler404 视图,则它必须返回带有HTTP 404状态代码的响应。使用 HttpResponseNotFound 或通过 status=404HttpResponse。否则,APPEND_SLASH 将无法与 DEBUG=False 正确工作。

特性在1.9中已弃用

assignment_tag()

Django 1.4添加了 assignment_tag 助手来简化创建将结果存储在模板变量中的模板标签。 simple_tag() 助手获得了同样的能力,使得 assignment_tag 过时。使用 assignment_tag 的标签应该更新为使用 simple_tag

带逗号分隔参数的 {% cycle %} 语法

cycle 标记支持来自以前的Django版本的劣质旧语法:

{% cycle row1,row2,row3 %}

它的解析导致与当前语法错误,因此对旧的语法的支持将在Django 1.10加速deprecation后删除。

ForeignKeyOneToOneField on_delete 参数

为了提高对级联模型删除的意识,在Django 2.0中将需要 ForeignKeyOneToOneFieldon_delete 参数。

更新模型和现有迁移以显式设置参数。由于默认值为 models.CASCADE,因此将 on_delete=models.CASCADE 添加到不使用不同选项的所有 ForeignKeyOneToOneField 。如果您不关心与旧版本的Django的兼容性,您还可以将其作为第二个位置参数。

Field.rel 更改

Field.rel 及其方法和属性已更改为与相关字段API匹配。 Field.rel 属性重命名为 remote_field,其许多方法和属性都要更改或重命名。

这些更改的目的是为关系字段提供一个记录的API。

GeoManagerGeoQuerySet 自定义方法

所有自定义 GeoQuerySet 方法(area()distance()gml(),...)已被注释中的等效地理表达式替换(参见新功能部分)。因此,需要为启用GIS的模型设置自定义 GeoManager 已经过时。只要您的代码不调用任何已弃用的方法,您就可以从模型中删除 objects = GeoManager() 行。

模板加载程序API已更改

Django模板加载器已更新,允许递归模板扩展。此更改需要一个新的模板加载器API。旧的 load_template()load_template_sources() 方法现已废弃。有关新API的详细信息,请参阅 在模板加载器文档中

将3元组或 app_name 传递给 include()

将元组作为参数传递给 include() 的实例命名空间部分已通过将 namespace 参数传递给 include() 来代替。例如:

polls_patterns = [
     url(...),
]

urlpatterns = [
    url(r'^polls/', include((polls_patterns, 'polls', 'author-polls'))),
]

成为:

polls_patterns = ([
     url(...),
], 'polls')  # 'polls' is the app_name

urlpatterns = [
    url(r'^polls/', include(polls_patterns, namespace='author-polls')),
]

include()app_name 参数已被替换为传递2元组(如上所述),或者传递具有 app_name 属性的对象或模块(如下所示)。如果 app_name 以这种新方式设置,则不再需要 namespace 参数。它将默认为 app_name 的值。例如,本教程中的网址格式从以下改变:

mysite/urls.py
urlpatterns = [
    url(r'^polls/', include('polls.urls', namespace="polls")),
    ...
]

至:

mysite/urls.py
urlpatterns = [
    url(r'^polls/', include('polls.urls')),  # 'namespace="polls"' removed
    ...
]
polls/urls.py
app_name = 'polls'  # added
urlpatterns = [...]

此更改还意味着包含 AdminSite 实例的旧方法已弃用。相反,将 admin.site.urls 直接传递到 url()

urls.py
from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

如果设置实例命名空间,则需要URL应用程序命名空间

在过去,没有应用程序命名空间的实例命名空间将具有与应用程序命名空间相同的目的,但是如果存在具有相同名称的应用程序命名空间,则不可能反转模式。包含指定实例命名空间的包含要求包含的URLconf设置应用程序命名空间。

contrib.auth 视图的 current_app 参数

django.contrib.auth.views 中的所有视图具有以下结构:

def view(request, ..., current_app=None, ...):

    ...

    if current_app is not None:
        request.current_app = current_app

    return TemplateResponse(request, template_name, context)

从Django 1.8开始,current_app 设置在 request 对象上。为了一致性,这些视图将要求调用者在 request 上设置 current_app,而不是在单独的参数中传递它。

django.contrib.gis.geoip

django.contrib.gis.geoip2 模块取代 django.contrib.gis.geoip。新模块提供了类似的API,但它不提供传统的GeoIP-Python API兼容性方法。

  • django.dispatch.signals.Signal.disconnect()weak 参数已被弃用,因为它没有效果。

  • django.db.backends.base.BaseDatabaseOperationscheck_aggregate_support() 方法已被弃用,并将在Django 2.0中删除。应使用更一般的 check_expression_support()

  • django.forms.extras 已弃用。你可以在 django.forms.widgets (或只是 django.forms)中找到 SelectDateWidget

  • 私有API django.db.models.fields.add_lazy_relation() 已弃用。

  • django.contrib.auth.tests.utils.skipIfCustomUser() 装饰器已弃用。由于Django 1.6中的测试发现更改,django.contrib 应用程序的测试不再作为用户项目的一部分运行。因此,@skipIfCustomUser 装饰器不再需要在 django.contrib.auth 中装饰测试。

  • 如果您定制了某些 错误处理程序,则仅弃用具有一个请求参数的视图签名。视图现在还应接受第二个 exception 位置参数。

  • django.utils.feedgenerator.Atom1Feed.mime_typedjango.utils.feedgenerator.RssFeed.mime_type 属性已被弃用,有利于 content_type

  • 如果使用无效的分隔符,Signer 现在发出警告。这将成为Django 1.10中的例外。

  • django.db.models.Field._get_val_from_obj() 已弃用,赞成 Field.value_from_object()

  • django.template.loaders.eggs.Loader 不推荐用作分发应用程序,因为不推荐鸡蛋。

  • 不推荐使用 SimpleTestCase.assertRaisesMessage()callable_obj 关键字参数。将可调用作为位置参数。

  • ModelAdmin 方法的 allow_tags 属性已被弃用。在构造方法的返回值时,请使用 format_html()format_html_join()mark_safe()

  • 不推荐使用 SyndicationFeed.add_item()enclosure 关键字参数。使用新的 enclosures 参数,它接受 Enclosure 对象的列表而不是单个对象。

  • django.template.base.Origindjango.template.loader.LoaderOrigindjango.template.base.StringOrigin 别名已弃用。

在1.9中删除的功能

这些功能已达到其折旧周期的末尾,并在Django 1.9中删除。有关详细信息,请参阅 特性在1.7中已弃用,包括如何删除这些功能的使用。

  • django.utils.dictconfig 被删除。

  • django.utils.importlib 被删除。

  • django.utils.tzinfo 被删除。

  • django.utils.unittest 被删除。

  • syncdb 命令被删除。

  • django.db.models.signals.pre_syncdbdjango.db.models.signals.post_syncdb

  • 删除对数据库路由器上的 allow_syncdb 的支持。

  • 自动同步应用程序而不迁移将被删除。所有应用都必须迁移,除非您通过 migrate --run-syncdb 选项。

  • 删除没有迁移的应用程序,sqlsqlallsqlclearsqldropindexessqlindexes 的SQL管理命令。

  • 支持自动加载 initial_data 夹具和初始SQL数据。

  • 所有模型都需要在已安装的应用程序中定义或声明显式 app_label。此外,在加载应用程序之前无法导入它们。特别是,不可能在应用程序的根包中导入模型。

  • 删除模型和形式 IPAddressField。存根字段保留与历史迁移的兼容性。

  • 不再支持 AppCommand.handle_app()

  • RequestSiteget_current_site() 不再可从 django.contrib.sites.models 导入。

  • 通过 runfcgi 管理命令的FastCGI支持被删除。

  • django.utils.datastructures.SortedDict 被删除。

  • ModelAdmin.declared_fieldsets 被删除。

  • 删除提供向后兼容性的 util 模块:

    • django.contrib.admin.util

    • django.contrib.gis.db.backends.util

    • django.db.backends.util

    • django.forms.util

  • ModelAdmin.get_formsets 被删除。

  • 引入将 BaseMemcachedCache._get_memcache_timeout() 方法重命名为 get_backend_timeout() 的向后兼容垫片被去除。

  • dumpdata--natural-n 选项被删除。

  • serializers.serialize()use_natural_keys 参数被删除。

  • 私有API django.forms.forms.get_declared_fields() 已删除。

  • 去除使用具有 DateTimeFieldSplitDateTimeWidget 的能力。

  • WSGIRequest.REQUEST 属性已删除。

  • 删除类 django.utils.datastructures.MergeDict

  • 删除 zh-cnzh-tw 语言代码。

  • 内部 django.utils.functional.memoize() 被删除。

  • django.core.cache.get_cache 被删除。

  • django.db.models.loading 被删除。

  • 将可调参数传递到查询集不再可能。

  • BaseCommand.requires_model_validation 被删除赞成 requires_system_checks。管理验证器由管理员检查替换。

  • ModelAdmin.validator_classdefault_validator_class 属性被删除。

  • ModelAdmin.validate() 被删除。

  • django.db.backends.DatabaseValidation.validate_field 被删除有利于 check_field 方法。

  • validate 管理命令已删除。

  • django.utils.module_loading.import_by_path 被删除赞成 django.utils.module_loading.import_string

  • ssiurl 模板标签从 future 模板标签库中删除。

  • django.utils.text.javascript_quote() 被删除。

  • 不再支持将数据库测试设置作为数据库设置中的独立条目,并以 TEST_ 作为前缀。

  • 删除了 ModelChoiceFieldModelMultipleChoiceFieldcache_choices 选项。

  • RedirectView.permanent 属性的默认值已从 True 更改为 False

  • django.contrib.sitemaps.FlatPageSitemap 被删除赞成 django.contrib.flatpages.sitemaps.FlatPageSitemap

  • 私有API django.test.utils.TestTemplateLoader 已删除。

  • django.contrib.contenttypes.generic 模块被删除。