Django 1.9发行说明

2015年12月1日

欢迎来到Django 1.9!

这些发行说明涵盖new features,以及从Django 1.8或更早版本升级时需要注意的一些backwards incompatible changes We’ve dropped some features that have reached the end of their deprecation cycle, and we’ve begun the deprecation process for some features.

如果要更新现有项目,请参阅Upgrading Django to a newer version指南。

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',
    },
]

有关详细信息,请参见Password validation

用于基于类视图的权限混合

Django现在随附AccessMixinLoginRequiredMixinPermissionRequiredMixinUserPassesTestMixin提供django.contrib.auth.decorators用于基于类的视图。 这些混合物已经从或被至少受到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级浏览器提供了全面的功能体验。 较旧的浏览器可能会遇到不同程度的优雅退化。

并行运行测试

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

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

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

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

次要功能

django.contrib.admin

  • 管理员视图现在具有model_adminadmin_site属性。
  • 默认情况下,管理员更改视图的URL已更改(位于/admin/<app>/<model>/<pk>/,现在位于/admin/<app>/<model>/<pk>/change/ 这不应该影响你的应用程序,除非你有硬编码的管理URL。 在这种情况下,请使用reversing admin URLs来替换这些链接。 请注意,旧的URL仍然重定向到新的,以便向后兼容,但可能会在以后的版本中删除。
  • 添加了ModelAdmin.get_list_select_related(),以便根据请求更改admin更改列表中使用的select_related()值。
  • 列出当前用户可用应用程序的available_apps上下文变量已添加到AdminSite.each_context()方法中。
  • 添加了AdminSite.empty_value_displayModelAdmin.empty_value_display以覆盖管理员更改列表中的空值显示。 您还可以自定义每个字段的值。
  • 在更改表单页面上添加或删除内联表单时添加了jQuery事件when an inline form is added or removed
  • 时间选择器小部件包含一个“6 p.m”选项,以便每6小时具有预定义选项的一致性。
  • JavaScript slug generation现在支持罗马尼亚字符。

django.contrib.admindocs

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

django.contrib.auth

  • PBKDF2密码缓存器的默认迭代次数已增加了20%。 这种向后兼容的更改不会影响具有子类django.contrib.auth.hashers.PBKDF2PasswordHasher的用户更改默认值。
  • The BCryptSHA256PasswordHasher will now update passwords if its rounds attribute is changed.
  • AbstractBaseUserBaseUserManager已被移动到新的django.contrib.auth.base_user模块,以便在不包含django.contrib.auth in INSTALLED_APPS(这样做在旧版本中引发了废弃警告,Django 1.9中不再支持)。
  • permission_required()的权限参数接受各种迭代,不仅仅是列表和元组。
  • 新的PersistentRemoteUserMiddleware可以使用REMOTE_USER来进行设置,其中标头仅在登录页面上填充,而不是会话中的每个请求。
  • password_reset()视图接受extra_email_context参数。

django.contrib.contenttypes

django.contrib.gis

  • All GeoQuerySet methods have been deprecated and replaced by equivalent database functions. 只要您的代码中替换了遗留方法,您甚至可以从启用GIS的类中删除特殊的GeoManager
  • GDAL接口现在支持从原始数据实例化基于文件和内存中的GDALRaster objects 添加了诸如投影或像素值等栅格属性的设置器。
  • 对于PostGIS用户,新的RasterField允许storing GDALRaster objects 它在保存模型时支持自动空间索引创建和重新投影。 它还不支持空间查询。
  • 新的GDALRaster.warp()方法允许通过指定目标光栅属性(如原点,宽度,高度或像素大小等)来对光栅进行翘曲。
  • 新的GDALRaster.transform()方法允许通过指定目标srid将光栅转换为不同的空间参考系统。
  • 新的GeoIP2类允许使用MaxMind的GeoLite2数据库,其中包括对IPv6地址的支持。
  • 小部件中包含的默认OpenLayers库版本已从2.13更新到2.13.1。

django.contrib.postgres

django.contrib.sessions

  • dbcached_db后端的会话模型和SessionStore类被重构以允许自定义数据库会话后端建立在它们之上。 有关更多详细信息,请参阅Extending database-backed session engines

django.contrib.sites

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

django.contrib.syndication

  • 已添加对每个Feed项目的多个机箱的支持。 如果在RSS订阅源上定义了多个机箱,与Atom订阅源不同,RSS提要会引发异常,因此每个Feed项目不支持多个机箱。

高速缓存¶ T0>

  • 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 ¶ T0>

数据库后端

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

文件存储

表格¶ T0>

  • ModelForm接受新的Meta选项field_classes来自定义字段的类型。 有关详细信息,请参见Overriding the default fields
  • 现在,您可以使用field_order属性,field_order构造函数参数或order_fields()方法来指定表单域的呈现顺序。
  • 表单前缀可以在表单类中指定,不仅在实例化表单时。 有关详细信息,请参阅Prefixes for forms
  • 您现在可以specify keyword arguments
  • SlugField现在接受一个allow_unicode参数,以允许在slugs中使用Unicode字符。
  • CharField现在接受strip参数,以取​​消前导和尾部空格的输入数据。 由于这是默认为True,这与以前的版本不同。
  • 表单字段现在支持disabled参数,允许显示窗口小部件被浏览器禁用。
  • 现在可以通过覆盖字段的get_bound_field()方法来自定义绑定字段。

通用视图

国际¶ T0>

  • django.views.i18n.set_language()现在可以正确地重定向到translated URLs
  • 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现在每个语言环境目录调用一次xgettext,而不是每个可翻译文件一次。 这加快了本地化建设。
  • blocktrans支持使用asvar将其输出分配给变量。
  • 有两种新的语言可供选择:哥伦比亚西班牙语和苏格兰盖尔语。

管理命令

  • 新的sendtestemail命令可让您发送测试电子邮件,以轻松确认通过Django发送的电子邮件正在运行。
  • 为了增加由sqlmigrate生成的SQL代码的可读性,为每个迁移操作生成的SQL代码之前是操作的描述。
  • 现在,确定性排序dumpdata命令输出。 此外,当指定--output选项时,它还显示终端中的进度条。
  • createcachetable命令现在有一个--dry-run标志来打印出SQL而不是执行它。
  • startapp命令创建一个apps.py文件。 由于它不使用default_app_configa discouraged API),您必须指定应用配置的路径,例如'polls.apps.PollsConfig',在INSTALLED_APPS中使用它(而不仅仅是'polls')。
  • 当使用PostgreSQL后端时,dbshell命令可以使用设置文件中的密码连接到数据库(而不需要手动输入)。
  • The django package may be run as a script, i.e. python -m django, which will behave the same as django-admin.
  • 具有--noinput选项的管理命令现在也采用--no-input作为该选项的别名。

迁移¶ T0>

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

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

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

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

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

    这种改进还要求Django不再支持混合迁移计划。 混合计划包括一些迁移列表,其中一些正在应用,另一些则是未应用的。 这从未受到官方支持,从来没有支持此行为的公共API。

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

模型¶ T0>

  • QuerySet.bulk_create()现在适用于代理模型。
  • 数据库配置获得了一个TIME_ZONE选项,用于与本地时间存储数据时间的数据库进行交互,当USE_TZTrue时,不支持时区。
  • RelatedManager.set()方法添加到由ForeignKeyGenericForeignKeyManyToManyField创建的相关经理。
  • 反向外键上的add()方法现在具有bulk参数,以允许执行一个查询,而不管添加的对象数量,而不是每个对象一个查询。
  • keep_parents参数添加到Model.delete()中,以允许仅删除使用多表继承的模型中的子级数据。
  • Model.delete()QuerySet.delete()返回删除的对象数。
  • 添加了一个系统检查,以防止在同一型号上定义Meta.orderingorder_with_respect_to
  • Date and time查找可以与其他查找链接(例如exact gtlt等)。 例如:Entry.objects.filter(pub_date__month__gt=6)
  • 所有数据库后端的时间查找(小时,分钟,秒)现在都由TimeField支持。 支持SQLite之外的后端添加,但在Django 1.7中没有文档。
  • 您可以指定Avg聚合的output_field参数,以便通过非数字列(例如DurationField)进行聚合。
  • date查找添加到DateTimeField,以允许仅通过日期部分查询该字段。
  • 添加了GreatestLeast数据库函数。
  • 添加了Now数据库函数,返回当前日期和时间。
  • Transform is now a subclass of Func() which allows Transforms to be used on the right hand side of an expression, just like regular Funcs. This allows registering some database functions like Length, Lower, and Upper as transforms.
  • SlugField现在接受一个allow_unicode参数,以允许在slugs中使用Unicode字符。
  • 添加了对QuerySet.distinct()中引用注释的支持。
  • connection.queries显示SQLite上带有替换参数的查询。
  • Query expressions can now be used when creating new model instances using save(), create(), and 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()来获取请求的始发端口。
  • json_dumps_params参数添加到JsonResponse以允许将关键字参数传递给用于生成响应的json.dumps()调用。
  • 当引用者等于所请求的URL时,BrokenLinkEmailsMiddleware现在将忽略404。 为了规避已经实施的空引用检查,一些Web bot将引用者设置为请求的URL。

模板¶ T0>

  • 使用simple_tag()帮助器创建的模板标签现在可以使用as参数将结果存储在模板变量中。
  • 添加了一个Context.setdefault()方法。
  • 添加了django.template记录器,并包含以下消息:
    • 缺少上下文变量的DEBUG级消息。
    • A WARNING level message for uncaught exceptions raised during the rendering of an {% include %} when debug mode is off (helpful since {% include %} silences the exception and returns an empty string).
  • firstof模板标签支持使用'as'将输出存储在变量中。
  • Context.update()现在可以用作上下文管理器。
  • Django模板加载器现在可以递归地扩展模板。
  • 调试页面模板postmortem包含来自安装的每个引擎的输出。
  • Debug page integration
  • DjangoTemplates后端可以通过模板OPTIONS显式注册库和内置函数。
  • 改进了timesincetimeuntil过滤器,以处理在给定大时间跨度时的闰年。
  • 现在,include标签在模板渲染期间缓存已解析的模板对象,从而加快了对for循环的重用。

测试¶ T0>

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

网址¶ T0>

  • 网址格式现在允许使用正则表达式查找断言。
  • 现在可以使用包含的模块或对象上的app_name属性来设置应用程序命名空间。 It can also be set by passing a 2-tuple of (<list of patterns>, <application namespace>) as the first argument to include().
  • 系统检查已被添加为常见的URL模式错误。

验证¶ T0>

1.9 中向后不兼容的更改

警告

除了本节中介绍的更改之外,请务必查看1.9中删除的Features removed in 1.9 如果您没有在特定功能的弃用时间轴内更新代码,则其删除可能会显示为向后不兼容的更改。

数据库后端API

  • 一些新的测试依赖于后端内部列缺省值(将结果返回为Field.default)的能力。 如果您的后端没有实现,您可以将can_introspect_default数据库功能设置为False 您可能需要查看Django包含的后端的实现(#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()混淆)。 这种方法用于在Oracle之前的1.0之前格式化日期,但是几年来还没有被任何核心后端覆盖,并且在Django的代码或测试中还没有被调用。

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

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

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

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

Django模板加载程序以前需要定义is_usable属性。 如果在模板设置中配置了加载程序,并且此属性为False,则将默认忽略加载程序。 实际上,这只是由egg loader使用,以检测是否安装了setuptools。 现在删除is_usable属性,而如果没有安装setuptools,那么egg loader在运行时会失败。

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

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

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

相对重定向不再转换为绝对URI。 RFC 2616 required the Location header in redirect responses to be an absolute URI, but it has been superseded by RFC 7231 which allows relative URIs in Location, recognizing the actual practice of user agents, almost all of which support them.

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

在极少数情况下,您需要旧的行为(用古代版本的Apache发现,使用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)

如果您不这样做,转换将像早期版本(具有弃用警告)一样执行,直到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

通常,模板标签不会自动切换其内容,并且这种行为是documented 对于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 set(默认值),则simple_tag将包含标签功能的输出与conditional_escape()

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

  • 生成HTML的任何代码都应使用模板系统或format_html()
  • 如果simple_tag的输出需要转义,请使用escape()conditional_escape()
  • 如果您绝对确定您从受信任的来源(例如,存储管理员输入的HTML的CMS字段)输出HTML,则可以使用mark_safe()标记。

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

Paginator.page_range

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

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

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

Implicit QuerySet __in lookup removed

在早期版本中,查询如:

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

将隐式转换为:

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

resulting in SQL like "related_id IN (SELECT id FROM ...)".

中隐含的__in

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

当安装Django 1.9或1.9.1 with setuptools 5.5.x时,您会看到:

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 安装 -U pip t0>也将升级setuptools。 这在Django的更高版本中解决,如Django 1.9.2 release notes中所述。

其它¶ T0>

  • contrib.admin中的jQuery静态文件已被移动到vendor/jquery子目录中。
  • 在管理更改列表list_display中显示的空列的文本已从(None)(或其翻译的等效项)更改为-(破折号)。
  • django.http.responses.REASON_PHRASESdjango.core.handlers.wsgi.STATUS_CODE_TEXT已被删除。 使用Python的stdlib而不是Python 2的http.client.responses和Python 2的httplib.responses
  • ValuesQuerySetValuesListQuerySet已被删除。
  • admin/base.html模板不再设置window.__admin_media_prefix__window.__admin_utc_offset__ 使用该值来构建绝对URL的JavaScript中的图像引用已被移动到CSS以便于自定义。 UTC偏移量存储在<body>标签的数据属性上。
  • CommaSeparatedIntegerField validation has been refined to forbid values like ',', ',1', and '1,,2'.
  • 表单初始化从ProcessFormView.get()方法移动到新的FormMixin.get_context_data()方法。 如果超过get_context_data()方法而不调用super(),则可能会向后不兼容。
  • 对PostGIS 1.5的支持已经下降。
  • django.contrib.sites.models.Site.domain字段已更改为unique
  • 为了执行测试隔离,默认情况下,在SimpleTestCase测试中不允许数据库查询。 您可以通过在测试类上将allow_database_queries类属性设置为True来禁用此行为。
  • ResolverMatch.app_name was changed to contain the full namespace path in the case of nested namespaces. 为了与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_appContext.current_app都未设置,那么url模板标签现在将使用当前请求的命名空间。 如果不想使用命名空间提示,请将request.current_app设置为None
  • SILENCED_SYSTEM_CHECKS设置现在将使所有级别的消息静音。 以前,将ERROR级别以上的消息打印到控制台。
  • The FlatPage.enable_comments field is removed from the FlatPageAdmin as it’s unused by the application. 如果您的项目或第三方应用程序使用它,create a custom 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 否则,DEBUG=FalseAPPEND_SLASH将无法正常工作。

功能在1.9 中不推荐使用

assignment_tag()

Django 1.4添加了assignment_tag帮助器,以便轻松创建将结果存储在模板变量中的模板标签。 simple_tag()助手已经获得了相同的功能,使得assignment_tag过时。 应该使用assignment_tag的标签更新为使用simple_tag

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

cycle标记支持先前Django版本的较旧的旧语法:

{% cycle row1,row2,row3 %}

它的解析引起了当前语法的错误,所以在加速弃用后,Django 1.10中将删除对旧语法的支持。

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(),...)通过注释中的等效地理表达式(参见新功能)。 因此,需要将自定义的GeoManager设置为支持GIS的模型现在已经过时了。 只要您的代码不调用任何已弃用的方法,您可以简单地删除对象 = GeoManager() 线。

模板加载程序API已更改

Django模板加载程序已更新,以允许递归模板扩展。 这种变化需要一个新的模板加载器API。 现在,不建议使用旧的load_template()load_template_sources()方法。 有关新API的详细信息可以在模板加载器文档中找到in the template loader documentation

传递一个3元组或一个app_nameinclude()

The instance namespace part of passing a tuple as an argument to include() has been replaced by passing the namespace argument to 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')),
]

The app_name argument to include() has been replaced by passing a 2-tuple (as above), or passing an object or module with an app_name attribute (as below). 如果以这种新方式设置了app_name,则不再需要namespace参数。 默认值为app_name 例如,教程中的URL模式从:

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
    ...
]
民调/ 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设置应用程序命名空间。

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起,在request对象上设置current_app 为了一致性,这些视图将要求调用者在request上设置current_app,而不是将其传递给单独的参数。

django.contrib.gis.geoip

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

其它¶ T0>

  • 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中的测试。
  • 如果您定制了一些error handlers,那么仅使用一个请求参数的视图签名已被弃用。 视图现在也应该接受第二个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()
  • The enclosure keyword argument to SyndicationFeed.add_item() is deprecated. 使用新的enclosures参数,它接受Enclosure对象的列表,而不是单个。
  • 对于django.template.base.Origindjango.template.loader.LoaderOrigindjango.template.base.StringOrigin别名已被弃用。

功能在1.9 中删除

这些功能已经到了它们的淘汰周期的终点,并在Django 1.9中被删除。 有关详细信息,请参见Features deprecated in 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()
  • 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语言代码。
  • The internal django.utils.functional.memoize() is removed.
  • 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模块被删除。