Django 1.9 发行说明 — Django 文档
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 AccessMixin、LoginRequiredMixin、PermissionRequiredMixin 和 UserPassesTestMixin,以提供 django.contrib.auth.decorators
[X] 的功能对于基于类的视图。 这些 mixin 取自或至少受到 django-braces 项目的启发。
不过,Django 和 django-braces
' 的实现有一些区别:
- raise_exception 属性只能是
True
或False
。 不支持自定义异常或可调用对象。 - 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_admin
或admin_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_display 和 ModelAdmin.empty_value_display 以覆盖管理更改列表中空值的显示。 您还可以自定义每个字段的值。
- 在更改表单页面上添加或删除内联表单时添加 jQuery 事件 [[Django/docs/3.0.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
现在将更新密码。 AbstractBaseUser
和BaseUserManager
被移动到一个新的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.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
- 添加了对 :lookup:`rangefield.contained_by` 查找的支持,用于某些与范围字段相对应的内置字段。
- 添加了 JSONField。
- 添加了 PostgreSQL 特定的聚合函数 。
- 新增 TransactionNow 数据库功能。
django.contrib.sessions
db
和cached_db
后端的会话模型和SessionStore
类被重构,以允许自定义数据库会话后端在它们的基础上构建。 有关更多详细信息,请参阅 扩展数据库支持的会话引擎 。
django.contrib.sites
- get_current_site() 现在处理
request.get_host()
返回domain:port
的情况,例如example.com:80
。 如果由于主机与数据库中的记录不匹配并且主机具有端口而导致查找失败,则会剥离该端口并仅使用域部分重试查找。
缓存
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
- 用于CSRF认证的请求头名称可以通过:setting:`CSRF_HEADER_NAME`自定义。
- CSRF 引用标头现在根据 :setting:`CSRF_COOKIE_DOMAIN` 设置进行验证(如果已设置)。 有关详细信息,请参阅 工作原理 。
- 新的 :setting:`CSRF_TRUSTED_ORIGINS` 设置提供了一种允许跨域不安全请求的方法(例如
POST
) 通过 HTTPS。
数据库后端
- PostgreSQL 后端 (
django.db.backends.postgresql_psycopg2
) 也可用作django.db.backends.postgresql
。 旧名称将继续可用以实现向后兼容性。
表格
- ModelForm 接受新的
Meta
选项field_classes
来自定义字段的类型。 有关详细信息,请参阅 覆盖默认字段 。 - 您现在可以使用 field_order 属性、
field_order
构造函数参数或 order_fields() 方法指定表单字段的呈现顺序。 - 表单前缀可以在表单类中指定,而不仅仅是在实例化表单时。 有关详细信息,请参阅 表单前缀 。
- 您现在可以 指定要传递给表单集中表单构造函数的关键字参数 。
- SlugField 现在接受 allow_unicode 参数以允许 slug 中的 Unicode 字符。
- CharField 现在接受一个 strip 参数来去除前导和尾随空格的输入数据。 由于这默认为
True
,这与以前的版本不同。 - 表单字段现在支持 disabled 参数,允许浏览器禁用显示字段小部件。
- 现在可以通过覆盖字段的 get_bound_field() 方法来自定义绑定字段。
通用视图
- 使用
as_view()
生成的基于类的视图现在具有view_class
和view_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_config
(a 不鼓励的 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.partial
和LazyObject
实例序列化的支持。当在 :setting:`MIGRATION_MODULES` 中提供
None
作为值时,Django 会将该应用程序视为没有迁移的应用程序。应用迁移时,运行 migrate 时显示的“渲染模型状态”步骤为详细程度 2 或更高,现在仅计算已应用的迁移的状态。 正在应用的迁移的模型状态是按需生成的,从而大大减少了所需的内存量。
然而,当不应用迁移时,这种改进是不可用的,因此仍然需要预先计算和存储中间迁移状态。
这一改进还要求 Django 不再支持混合迁移计划。 混合计划由迁移列表组成,其中一些正在应用,而另一些则未应用。 这从未得到官方支持,也从未有过支持此行为的公共 API。
:djadmin:`squashmigrations` 命令现在支持指定迁移将被压缩的起始迁移。
型号
- QuerySet.bulk_create() 现在适用于代理模型。
- 数据库配置获得了 :设置:`TIME_ZONE ` 用于与以本地时间存储日期时间且不支持时区的数据库交互的选项 :设置:`USE_TZ` 是
True
. - 为
ForeignKey
、GenericForeignKey
、ManyToManyField
创建的相关管理器增加了RelatedManager.set()方法。 - 反向外键上的 add() 方法现在有一个
bulk
参数,无论添加多少对象,都允许执行一个查询,而不是每个对象一个查询。 - 将
keep_parents
参数添加到 Model.delete() 以允许仅删除使用多表继承的模型中的子数据。 - Model.delete() 和 QuerySet.delete() 返回删除的对象数。
- 添加了系统检查以防止在同一型号上同时定义
Meta.ordering
和order_with_respect_to
。 - :lookup:`日期和时间 ` 查找可以与其他查找链接(例如 :查找:`精确` , :查找:`gt` , :查找:`lt` , 等等。)。 例如:
Entry.objects.filter(pub_date__month__gt=6)
。 - TimeField 现在支持所有数据库后端的时间查找(小时、分钟、秒)。 添加了对 SQLite 以外的后端的支持,但在 Django 1.7 中没有记录。
- 您可以指定 Avg 聚合的
output_field
参数,以便聚合非数字列,例如DurationField
。 - 将 :lookup:`date` 查找添加到 DateTimeField 以允许仅通过日期部分查询字段。
- 添加了 Greatest 和 Least 数据库函数。
- 添加了 Now 数据库函数,该函数返回当前日期和时间。
- Transform 现在是 Func() 的子类,它允许
Transform
用于表达式的右侧,就像常规的Func
]s。 这允许注册一些数据库函数,如 Length、Lower 和 Upper 作为转换。 - SlugField 现在接受 allow_unicode 参数以允许 slug 中的 Unicode 字符。
- 添加了对在
QuerySet.distinct()
中引用注释的支持。 connection.queries
显示在 SQLite 上使用替换参数的查询。- 现在可以在使用
save()
、create()
和bulk_create()
创建新模型实例时使用查询表达式 。
请求和响应
- 除非 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模板后端获得了通过模板显式注册库和内置函数的能力 :设置:`选项 ` .
timesince
和timeuntil
过滤器经过改进,可以在给定大时间跨度时处理闰年。include
标签现在在模板渲染期间缓存解析的模板对象,加快在诸如 for 循环等地方的重用。
测试
- 添加了 json() 方法来测试客户端响应,以便以 JSON 形式访问响应正文。
- 向测试客户端添加了 force_login() 方法。 使用此方法模拟用户登录网站的效果,同时跳过 login() 的身份验证和验证步骤。
网址
- URL 模式中现在允许使用正则表达式环视断言。
- 现在可以使用包含的模块或对象上的
app_name
属性设置应用程序命名空间。 也可以通过传递 ( , ) 作为第一个参数include()
. - 添加了针对常见 URL 模式错误的系统检查。
验证器
- 添加了 django.core.validators.int_list_validator() 以生成包含用自定义字符分隔的整数的字符串的验证器。
- EmailValidator 现在将域名标签的长度限制为每个 RFC 1034 的 63 个字符。
- 添加了 validate_unicode_slug() 以验证可能包含 Unicode 字符的 slug。
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.Loader 或 app_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.LoaderOrigin
或 django.template.base.StringOrigin
的实例被设置为模板对象的原点属性。 这些类已合并到 Origin 中,现在无论引擎调试设置如何,都始终设置。 为了最小的向后兼容性,旧的类名将作为新的 Origin
类的别名保留,直到 Django 2.0。
对默认日志记录配置的更改
为了更容易编写自定义日志配置,Django 的默认日志配置不再定义 django.request
和 django.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_PHRASES
和django.core.handlers.wsgi.STATUS_CODE_TEXT
已被移除。 改用 Python 的 stdlib:http.client.responses
for Python 3 和 httplib.responses for Python 2。ValuesQuerySet
和ValuesListQuerySet
已被移除。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_app 和 Context.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
,重命名如下:ReverseSingleRelatedObjectDescriptor
是ForwardManyToOneDescriptor
SingleRelatedObjectDescriptor
是ReverseOneToOneDescriptor
ForeignRelatedObjectsDescriptor
是ReverseManyToOneDescriptor
ManyRelatedObjectsDescriptor
是ManyToManyDescriptor
- 如果您实现自定义 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 中将需要 ForeignKey
和 OneToOneField
的 on_delete
参数。
更新模型和现有迁移以显式设置参数。 由于默认值为 models.CASCADE
,因此将 on_delete=models.CASCADE
添加到所有不使用不同选项的 ForeignKey
和 OneToOneField
。 如果您不关心与旧版本 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 模式从:
urlpatterns = [
url(r'^polls/', include('polls.urls', namespace="polls")),
...
]
到:
urlpatterns = [
url(r'^polls/', include('polls.urls')), # 'namespace="polls"' removed
...
]
app_name = 'polls' # added
urlpatterns = [...]
此更改还意味着不推荐使用包含 AdminSite
实例的旧方法。 相反,将 admin.site.urls
直接传递给 url():
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.BaseDatabaseOperations
的check_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_type
和django.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.Origin
的django.template.loader.LoaderOrigin
和django.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_syncdb
和django.db.models.signals.post_syncdb
被移除。- 删除了对数据库路由器上的
allow_syncdb
的支持。 - 删除了无需迁移的应用程序自动同步。 除非您通过
migrate --run-syncdb
选项,否则所有应用程序都必须进行迁移。 - 没有迁移的应用程序的 SQL 管理命令
sql
、sqlall
、sqlclear
、sqldropindexes
和sqlindexes
被删除。 - 删除了对自动加载
initial_data
装置和初始 SQL 数据的支持。 - 所有模型都需要在已安装的应用程序中定义或声明显式 app_label。 此外,在加载应用程序之前无法导入它们。 特别是,不可能在应用程序的根包内导入模型。
- 模型和表格
IPAddressField
被删除。 存根字段保留以与历史迁移兼容。 - 不再支持
AppCommand.handle_app()
。 RequestSite
和get_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()
。 - 移除了将
SplitDateTimeWidget
与DateTimeField
一起使用的功能。 WSGIRequest.REQUEST
属性被移除。- 类
django.utils.datastructures.MergeDict
被删除。 zh-cn
和zh-tw
语言代码被删除。- 内部
django.utils.functional.memoize()
被移除。 django.core.cache.get_cache
被移除。django.db.models.loading
被移除。- 不再可能将可调用参数传递给查询集。
BaseCommand.requires_model_validation
被移除以支持 [X33X]。 管理员验证器被管理员检查取代。ModelAdmin.validator_class
和default_validator_class
属性被移除。ModelAdmin.validate()
被移除。django.db.backends.DatabaseValidation.validate_field
被移除以支持 [X37X] 方法。validate
管理命令被删除。django.utils.module_loading.import_by_path
被移除以支持 [X33X]。ssi
和url
模板标签从future
模板标签库中移除。django.utils.text.javascript_quote()
被移除。- 不再支持数据库测试设置作为数据库设置中的独立条目,前缀为
TEST_
。 - ModelChoiceField 和 ModelMultipleChoiceField 的
cache_choices
选项被删除。 - RedirectView.permanent 属性的默认值已从
True
更改为False
。 django.contrib.sitemaps.FlatPageSitemap
被移除以支持 [X33X]。- 删除了私有 API
django.test.utils.TestTemplateLoader
。 django.contrib.contenttypes.generic
模块被移除。