Django 1.9 发行说明 — Django 文档

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

Django 1.9 发行说明

2015 年 12 月 1 日

欢迎使用 Django 1.9!

这些发行说明涵盖了 新功能 ,以及从 Django 1.8 或更旧版本升级时您需要注意的一些 向后不兼容更改 。 我们已经 删除了一些已达到弃用周期结束的功能 ,并且我们已经 开始了一些功能 的弃用过程。

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

Python兼容性

Django 1.9 需要 Python 2.7、3.4 或 3.5。 我们【X3X】强烈推荐【X23X】,官方只支持各系列的最新版本。

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


Django 1.9 中的新功能

在事务提交后执行操作

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

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


密码验证

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

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

默认情况下,不执行验证并且接受所有密码,因此如果您不设置 :setting:`AUTH_PASSWORD_VALIDATORS`,您将看不到任何更改。 在使用默认 :djadmin:`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 现在随附了 mixins AccessMixinLoginRequiredMixinPermissionRequiredMixinUserPassesTestMixin,以提供 django.contrib.auth.decorators[X] 的功能对于基于类的视图。 这些 mixin 取自或至少受到 django-braces 项目的启发。

不过,Django 和 django-braces' 的实现有一些区别:

  • raise_exception 属性只能是 TrueFalse。 不支持自定义异常或可调用对象。
  • handle_no_permission() 方法不接受 request 参数。 当前请求在 self.request 中可用。
  • UserPassesTestMixin 的自定义 test_func() 不接受 user 参数。 当前用户在 self.request.user 中可用。
  • permission_required 属性支持需要满足以授予访问权限的字符串(定义一个权限)或字符串列表/元组(定义多个权限)。
  • 新的 permission_denied_message 属性允许将消息传递给 PermissionDenied 异常。


contrib.admin 的新样式

管理员采用现代、扁平的设计,带有新的 SVG 图标,在 HiDPI 屏幕上看起来很完美。 它仍然为 YUI 的 A 级 浏览器提供全功能体验。 较旧的浏览器可能会遇到不同程度的优雅降级。


并行运行测试

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

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

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

  • 操作系统支持它(除了 Windows)
  • 数据库后端支持它(除 Oracle 外的所有内置后端)


小功能

django.contrib.admin

  • 管理员视图现在具有 model_adminadmin_site 属性。
  • 管理员更改视图的 URL 已更改(默认位于 /admin/<app>/<model>/<pk>/,现在位于 /admin/<app>/<model>/<pk>/change/)。 除非您有硬编码的管理 URL,否则这不会影响您的应用程序。 在这种情况下,请通过 反向管理 URL 替换这些链接。 请注意,旧 URL 仍会重定向到新 URL 以实现向后兼容性,但它可能会在未来版本中删除。
  • 添加 ModelAdmin.get_list_select_related() 以允许根据请求更改管理员更改列表查询中使用的 select_related() 值。
  • available_apps 上下文变量列出了当前用户的可用应用程序,已添加到 AdminSite.each_context() 方法中。
  • 添加了 AdminSite.empty_value_displayModelAdmin.empty_value_display 以覆盖管理更改列表中空值的显示。 您还可以自定义每个字段的值。
  • 在更改表单页面上添加或删除内联表单时添加 jQuery 事件 [[Django/docs/3.2.x/ref/contrib/admin/javascript#admin-javascript-inline-form-events|]]。
  • 时间选择器小部件包括一个“下午 6 点”选项,以保持每 6 小时具有预定义选项的一致性。
  • JavaScript slug 生成现在支持罗马尼亚语字符。


django.contrib.admindocs

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


django.contrib.auth

  • PBKDF2 密码哈希器的默认迭代次数增加了 20%。 这种向后兼容的更改不会影响子类化 django.contrib.auth.hashers.PBKDF2PasswordHasher 的用户更改默认值。
  • 如果 rounds 属性更改,BCryptSHA256PasswordHasher 现在将更新密码。
  • AbstractBaseUserBaseUserManager 被移动到一个新的 django.contrib.auth.base_user 模块,以便它们可以被导入而无需在 中包含 django.contrib.auth:setting:`INSTALLED_APPS`[ X150X](这样做会在旧版本中引发弃用警告,并且在 Django 1.9 中不再受支持)。
  • permission_required() 的权限参数接受各种可迭代对象,不仅仅是列表和元组。
  • 新的 PersistentRemoteUserMiddleware 可以使用 REMOTE_USER 进行设置,其中标头仅填充在登录页面而不是会话中的每个请求。
  • django.contrib.auth.views.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

  • 添加了对每个提要项目的多个机箱的支持。 如果在 RSS 提要上定义了多个附件,则会引发异常,因为 RSS 提要与 Atom 提要不同,不支持每个提要项目有多个附件。


缓存

  • django.core.cache.backends.base.BaseCache 现在有一个 get_or_set() 方法。
  • django.views.decorators.cache.never_cache() 现在发送更具说服力的标头(将 no-cache, no-store, must-revalidate 添加到 Cache-Control)以更好地防止缓存。 这也是在 Django 1.8.8 中添加的。


CSRF


数据库后端

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


文件存储


表格


通用视图

  • 使用 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 对象。
  • :ttag:`get_language_info` 模板标签返回的对象添加了 name_translated 属性。 还添加了相应的模板过滤器::tfilter:`language_name_translated`
  • 您现在可以从项目的根目录运行 :djadmin:`compilemessages`,它会找到所有由 :djadmin:`makemessages` 创建的应用消息文件。
  • :djadmin:`makemessages` 现在每个语言环境目录调用一次 xgettext,而不是每个可翻译文件调用一次。 这加快了本地化构建。
  • :ttag:`blocktrans` 支持使用 asvar 将其输出分配给变量。
  • 提供两种新语言:哥伦比亚西班牙语和苏格兰盖尔语。


管理命令

  • 新的 :djadmin:`sendtestemail` 命令可让您发送测试电子邮件以轻松确认通过 Django 发送的电子邮件是否有效。
  • 为了增加生成的SQL代码的可读性:djadmin:`sqlmigrate`,每个迁移操作生成的SQL代码前面都有操作说明。
  • :djadmin:`dumpdata` 命令输出现在是确定性排序的。 此外,当指定 --output 选项时,它还会在终端中显示一个进度条。
  • :djadmin:`createcachetable` 命令现在有一个 --dry-run 标志来打印 SQL 而不是执行它。
  • :djadmin:`startapp` 命令创建一个 apps.py 文件。 由于它不使用 default_app_configa 不鼓励的 API),你必须指定应用配置的路径,例如 'polls.apps.PollsConfig',在 :setting:`INSTALLED_APPS` 中使用它(而不是仅仅 'polls')。
  • 使用 PostgreSQL 后端时,:djadmin:`dbshell` 命令可以使用设置文件中的密码连接到数据库(而不是要求手动输入)。
  • django 包可以作为脚本运行,即 python -m django,其行为与 django-admin 相同。
  • 具有 --noinput 选项的管理命令现在也将 --no-input 作为该选项的别名。


迁移

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

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

  • 当在 :setting:`MIGRATION_MODULES` 中提供 None 作为值时,Django 会将该应用程序视为没有迁移的应用程序。

  • 应用迁移时,运行 migrate 时显示的“渲染模型状态”步骤为详细程度 2 或更高,现在仅计算已应用的迁移的状态。 正在应用的迁移的模型状态是按需生成的,从而大大减少了所需的内存量。

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

    这一改进还要求 Django 不再支持混合迁移计划。 混合计划由迁移列表组成,其中一些正在应用,而另一些则未应用。 这从未得到官方支持,也从未有过支持此行为的公共 API。

  • :djadmin:`squashmigrations` 命令现在支持指定迁移将被压缩的起始迁移。


型号


请求和响应

  • 除非 HttpResponse.reason_phrase 被明确设置,它现在由 HttpResponse.status_code 的当前值决定。 在构造函数之外修改 status_code 的值也会修改 reason_phrase 的值。
  • 调试视图现在显示 Python 3 上链式异常的详细信息。
  • 默认的 40x 错误视图现在接受第二个位置参数,触发视图的异常。
  • 视图错误处理程序现在支持 [X32X]TemplateResponse,通常用于基于类的视图。
  • render() 方法引发的异常现在传递给每个中间件的 process_exception() 方法。
  • 请求中间件现在可以将 HttpRequest.urlconf 设置为 None 以恢复以前中间件所做的任何更改并返回使用 :setting:`ROOT_URLCONF`
  • :setting:`DISALLOWED_USER_AGENTS` 检入 CommonMiddleware 现在会引发 PermissionDenied 异常,而不是返回 HttpResponseForbidden 以便 handler403 被调用。
  • 添加了 HttpRequest.get_port() 以获取请求的原始端口。
  • json_dumps_params 参数添加到 JsonResponse 以允许将关键字参数传递给用于生成响应的 json.dumps() 调用。
  • BrokenLinkEmailsMiddleware 现在在引用者等于请求的 URL 时忽略 404。 为了规避已经实施的空引用检查,一些网络机器人将引用设置为请求的 URL。


模板

  • 使用 simple_tag() 助手创建的模板标签现在可以使用 as 参数将结果存储在模板变量中。
  • 添加了 Context.setdefault() 方法。
  • 添加了 django.template 记录器并包含以下消息:
    • 缺少上下文变量的 DEBUG 级别消息。
    • 当调试模式关闭时,在渲染 {% include %} 期间引发的未捕获异常的 WARNING 级别消息(很有用,因为 {% include %} 使异常静音并返回一个空字符串)。
  • :ttag:`firstof` 模板标签支持使用“as”将输出存储在变量中。
  • Context.update() 现在可以用作上下文管理器。
  • Django 模板加载器现在可以递归扩展模板。
  • 调试页面模板事后分析现在包括来自安装的每个引擎的输出。
  • 添加了自定义模板引擎的调试页面集成
  • Django模板后端获得了通过模板显式注册库和内置函数的能力 :设置:`选项 ` .
  • timesincetimeuntil 过滤器经过改进,可以在给定大时间跨度时处理闰年。
  • include 标签现在在模板渲染期间缓存解析的模板对象,加快在诸如 for 循环等地方的重用。


测试

  • 添加了 json() 方法来测试客户端响应,以便以 JSON 形式访问响应正文。
  • 向测试客户端添加了 force_login() 方法。 使用此方法模拟用户登录网站的效果,同时跳过 login() 的身份验证和验证步骤。


网址

  • URL 模式中现在允许使用正则表达式环视断言。
  • 现在可以使用包含的模块或对象上的 app_name 属性设置应用程序命名空间。 也可以通过传递 ( , ) 作为第一个参数include() .
  • 添加了针对常见 URL 模式错误的系统检查。


验证器


1.9 中向后不兼容的更改

警告

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


数据库后端API

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

  • 不鼓励在 DB-API 模块级别注册全局适配器或转换器来处理 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 loader 用来检测是否安装了 setuptools。 is_usable 属性现在被删除,如果没有安装 setuptools,egg 加载器会在运行时失败。


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

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


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

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

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

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

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 版本。


模板 LoaderOrigin 和 StringOrigin 被移除

在以前的 Django 版本中,当模板引擎使用 debug 初始化为 True 时,django.template.loader.LoaderOrigindjango.template.base.StringOrigin 的实例被设置为模板对象的原点属性。 这些类已合并到 Origin 中,现在无论引擎调试设置如何,都始终设置。 为了最小的向后兼容性,旧的类名将作为新的 Origin 类的别名保留,直到 Django 2.0。


对默认日志记录配置的更改

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

  • console:在 INFO 级别过滤,仅在 DEBUG=True 时有效。
  • mail_admins:在 ERROR 级别过滤,仅在 DEBUG=False 时有效。

例如,如果您没有覆盖 Django 的默认日志记录,您应该会看到行为的最小变化,但您可能会看到一些新的日志记录到 runserver 控制台。

如果您要覆盖 Django 的默认日志记录,您应该检查您的配置如何与新的默认值合并。


HttpRequest 错误报告中的详细信息

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

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


删除日期时间的时区感知全局适配器和转换器

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

  • :setting:`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)

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

如果您从结果中读取 datetime 值,它们将是幼稚的而不是意识到的。 您可以按以下方式进行补偿:

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

如果您通过 ORM 查询数据库,则不需要任何这些,即使您正在使用 raw() 查询。 ORM 负责管理时区信息。


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

DjangoTemplates 后端现在在实例化时对已安装的模板标签模块执行发现。 此更新使库能够通过显式提供'libraries'的关键 :设置:`选项 ` 当定义一个 Django模板后端。 模板标签模块中的导入或语法错误现在在实例化时提前失败,而不是在模板带有 :ttag:`{% 加载 %} ` 标签首先被编译。


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

虽然是私有API,但项目常用add_to_builtins()使模板标签和过滤器可用而不使用 :ttag:`{% 加载 %} ` 标签。 此 API 已正式化。 项目现在应该通过'builtins'的关键 :设置:`选项 ` 当定义一个 Django模板后端。


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(例如 一个存储管理员输入的 HTML 的 CMS 字段),您可以使用 mark_safe() 将其标记为这样。

遵循这些规则的标签无论是在 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 及更早版本不支持这些图标。

嵌入在 admin 中的 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,您可以使用 python -m pip install -U pip 升级 pip,这也将升级 setuptools。 如 Django 1.9.2 发行说明 中所述,此问题在 Django 的更高版本中得到解决。


杂项

  • contrib.admin 中的 jQuery 静态文件已移动到 vendor/jquery 子目录中。
  • 管理更改列表 list_display 单元格中为空列显示的文本已从 (None)(或其翻译的等效项)更改为 -(破折号)。
  • django.http.responses.REASON_PHRASESdjango.core.handlers.wsgi.STATUS_CODE_TEXT 已被移除。 改用 Python 的 stdlib:http.client.responses for Python 3 和 httplib.responses for Python 2。
  • ValuesQuerySetValuesListQuerySet 已被移除。
  • admin/base.html 模板不再设置 window.__admin_media_prefix__window.__admin_utc_offset__。 JavaScript 中使用该值构建绝对 URL 的图像引用已移至 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 序列化(通过 :djadmin:`dumpdata` 或联合框架)用于输出它收到的任何字符。 现在,如果要序列化的内容包含 XML 1.0 标准中不允许的任何控制字符,则序列化将失败并显示 ValueError
  • CharField 现在默认去除前导和尾随空格的输入。 这可以通过将新的 strip 参数设置为 False 来禁用。
  • 已翻译并使用两个或多个连续百分号的模板文本,例如 "%%",在makemessages运行后可能会有一个新的msgid(很可能翻译会被标记为模糊)。 新的 msgid 将标记为 "#, python-format"
  • 如果 request.current_appContext.current_app 都没有设置,:ttag:`url` 模板标签现在将使用当前请求的命名空间。 如果您不想使用命名空间提示,请将 request.current_app 设置为 None
  • :setting:`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=404 传递给 HttpResponse。 否则,:setting:`APPEND_SLASH` 将无法与 DEBUG=False 一起正常工作。


1.9 中弃用的功能

assignment_tag()

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


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

:ttag:`cycle` 标签支持旧 Django 版本的劣等语法:

{% cycle row1,row2,row3 %}

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


ForeignKey 和 OneToOneField 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。


GeoManager 和 GeoQuerySet 自定义方法

所有自定义 GeoQuerySet 方法(area()distance()gml()、...)已被注释中的等效地理表达式替换(参见新功能)。 因此,现在不再需要将自定义 GeoManager 设置为启用 GIS 的模型。 只要您的代码没有调用任何已弃用的方法,您就可以简单地从模型中删除 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 的值。 例如,教程中的 URL 模式从:

我的网站/urls.py

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

到:

我的网站/urls.py

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

民意调查/网址.py

app_name = 'polls'  # added
urlpatterns = [...]

此更改还意味着不推荐使用包含 AdminSite 实例的旧方法。 相反,将 admin.site.urls 直接传递给 django.conf.urls.url()

网址.py

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

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

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

过去,没有应用程序命名空间的实例命名空间与应用程序命名空间的用途相同,但如果存在同名的应用程序命名空间,则无法逆转模式。 指定实例命名空间的包含要求包含的 URLconf 设置应用程序命名空间。


current_app 参数到 contrib.auth 视图

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 选项,否则所有应用程序都必须进行迁移。
  • 没有迁移的应用程序的 SQL 管理命令 sqlsqlallsqlclearsqldropindexessqlindexes 被删除。
  • 删除了对自动加载 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() 而引入的向后兼容垫片。
  • :djadmin:`dumpdata`--natural-n 选项被删除。
  • serializers.serialize()use_natural_keys 参数被删除。
  • 删除了私有 API django.forms.forms.get_declared_fields()
  • 移除了将 SplitDateTimeWidgetDateTimeField 一起使用的功能。
  • 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 被移除以支持 [X33X]。 管理员验证器被管理员检查取代。
  • ModelAdmin.validator_classdefault_validator_class 属性被移除。
  • ModelAdmin.validate() 被移除。
  • django.db.backends.DatabaseValidation.validate_field 被移除以支持 [X37X] 方法。
  • validate 管理命令被删除。
  • django.utils.module_loading.import_by_path 被移除以支持 [X33X]。
  • ssiurl 模板标签从 future 模板标签库中移除。
  • django.utils.text.javascript_quote() 被移除。
  • 不再支持数据库测试设置作为数据库设置中的独立条目,前缀为 TEST_
  • ModelChoiceFieldModelMultipleChoiceFieldcache_choices 选项被删除。
  • RedirectView.permanent 属性的默认值已从 True 更改为 False
  • django.contrib.sitemaps.FlatPageSitemap 被移除以支持 [X33X]。
  • 删除了私有 API django.test.utils.TestTemplateLoader
  • django.contrib.contenttypes.generic 模块被移除。