Django 2.0 发行说明 — Django 文档

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

Django 2.0 发行说明

2017 年 12 月 2 日

欢迎来到 Django 2.0!

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

此版本开始 Django 使用 松散形式的语义版本控制 ,但没有任何可能在 2.0 版本中预期的向后不兼容的重大更改。 升级的工作量应该与过去的功能版本相似。

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

Python兼容性

Django 2.0 支持 Python 3.4、3.5、3.6 和 3.7。 我们【X3X】强烈推荐【X23X】,官方只支持各系列的最新版本。

Django 1.11.x 系列是最后一个支持 Python 2.7 的。

Django 2.0 将是最后一个支持 Python 3.4 的发布系列。 如果您计划在 Django 2.0(2019 年 4 月)生命周期结束后部署 Python 3.4,请坚持使用 Django 1.11 LTS(支持至 2020 年 4 月)。 但是请注意,Python 3.4 的生命周期结束时间是 2019 年 3 月。


对旧版本 Django 的第三方库支持

在 Django 2.0 发布之后,我们建议第三方应用程序作者放弃对 Django 1.11 之前的所有版本的支持。 那时,您应该能够使用 python -Wd 运行包的测试,以便出现弃用警告。 修复弃用警告后,您的应用程序应该与 Django 2.0 兼容。


Django 2.0 中的新功能

简化的 URL 路由语法

新的 django.urls.path() 函数允许更简单、更易读的 URL 路由语法。 例如,以前的 Django 版本中的这个例子:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

可以写成:

path('articles/<int:year>/', views.year_archive),

新语法支持 URL 参数的类型强制。 在示例中,视图将接收 year 关键字参数作为整数而不是字符串。 此外,在重写的示例中,将匹配的 URL 受到的限制略少。 例如,年份 10000 现在将匹配,因为年份整数不受正则表达式中的严格限制为四位数字。

以前版本的 django.conf.urls.url() 函数现在作为 django.urls.re_path() 可用。 旧位置保留为向后兼容,没有即将弃用。 旧的 django.conf.urls.include() 函数现在可以从 django.urls 导入,因此您可以在 URLconfs 中使用 from django.urls import include, path, re_path

URL 调度程序 文档被重写以具有新语法并提供更多详细信息。


移动友好 contrib.admin

管理员现在可以响应并支持所有主要的移动设备。 较旧的浏览器可能会遇到不同程度的优雅降级。


窗口表达式

新的 Window 表达式允许向查询集添加 OVER 子句。 您可以在表达式中使用 窗口函数聚合函数


小功能

django.contrib.admin


django.contrib.auth

  • PBKDF2 密码哈希器的默认迭代计数从 36,000 增加到 100,000。


django.contrib.gis


django.contrib.postgres

  • ArrayAgg 的新 distinct 参数确定连接的值是否不同。
  • 新的 RandomUUID 数据库函数返回版本 4 UUID。 它需要使用 PostgreSQL 的 pgcrypto 扩展,可以使用新的 CryptoExtension 迁移操作激活该扩展。
  • django.contrib.postgres.indexes.GinIndex 现在支持 fastupdategin_pending_list_limit 参数。
  • 新的 GistIndex 类允许在数据库中创建 GiST 索引。 新的 BtreeGistExtension 迁移操作安装了 btree_gist 扩展以添加对非内置运算符类的支持。
  • :djadmin:`inspectdb` 现在可以自省 JSONField 和各种 RangeFielddjango.contrib.postgres 必须在 INSTALLED_APPS 中)。


django.contrib.sitemaps


缓存

  • cache.set_many() 现在返回未能插入的密钥列表。 对于内置后端,插入失败只能发生在 memcached 上。


文件存储

  • File.open() 可以用作上下文管理器,例如 with file.open() as f:


表格


通用视图


管理命令

  • :djadmin:`inspectdb` 现在将 MySQL 的无符号整数列转换为 PositiveIntegerFieldPositiveSmallIntegerField
  • 新的 makemessages --add-location 选项控制 PO 文件中的注释格式。
  • :djadmin:`loaddata` 现在可以 从 stdin 读取。
  • 新的 diffsettings --output 选项允许以统一的差异格式格式化输出。
  • 在 Oracle 上,如果将列创建为标识列,:djadmin:`inspectdb` 现在可以自省 AutoField
  • 在 MySQL 上,:djadmin:`dbshell` 现在支持客户端 TLS 证书。


迁移

  • 新的 squashmigrations --squashed-name 选项允许命名压缩的迁移。


型号


请求和响应


模板

  • 为了增加 Engine.get_default() 在第三方应用程序中的实用性,如果在 TEMPLATES 中配置多个 DjangoTemplates 引擎,它现在返回第一个引擎,而不是提高 [ X191X]。
  • 自定义模板标签现在可以接受仅关键字参数。


测试


验证器

  • 新的 ProhibitNullCharactersValidator 不允许在 CharField 表单字段及其子类的输入中使用空字符。 从漏洞扫描工具中观察到空字符输入。 大多数数据库会默默地丢弃空字符,但 psycopg2 2.7+ 在尝试使用 PostgreSQL 将空字符保存到字符/文本字段时引发异常。


2.0 中向后不兼容的变化

在某些地方删除了对字节串的支持

为了支持原生 Python 2 字符串,较旧的 Django 版本必须同时接受字节字符串和 Unicode 字符串。 既然 Python 2 支持已被删除,字节串只能在输入/输出边界附近遇到(例如,处理二进制字段或 HTTP 流)。 您可能需要更新代码以将字节串的使用限制在最低限度,因为 Django 不再接受某些代码路径中的字节串。 Python 的 -b 选项可能有助于检测代码中的错误。

例如,reverse() 现在使用 str() 而不是 force_text() 来强制它接收到的 argskwargs,然后再将它们放入网址。 对于字节串,这会创建一个带有不需要的 b 前缀和附加引号的字符串(str(b'foo')"b'foo'")。 为了适应,在将字节串传递给 reverse() 之前调用 decode()


数据库后端API

本节介绍第三方数据库后端可能需要的更改。

  • DatabaseOperations.datetime_cast_date_sql()datetime_cast_time_sql()datetime_trunc_sql()datetime_extract_sql()date_interval_sql() 方法现在只返回执行操作的 SQL 而不是 SQL 和参数列表。
  • 第三方数据库后端应添加一个 DatabaseWrapper.display_name 属性,其中包含您的后端使用的数据库的名称。 Django 可能会在各种消息中使用它,例如在系统检查中。
  • SchemaEditor._alter_column_type_sql() 的第一个参数现在是 model 而不是 table
  • SchemaEditor._create_index_name() 的第一个参数现在是 table_name 而不是 model
  • 要启用 FOR UPDATE OF 支持,请设置 DatabaseFeatures.has_select_for_update_of = True。 如果数据库要求 OF 的参数是列而不是表,请设置 DatabaseFeatures.select_for_update_of_column = True
  • 要启用对 Window 表达式的支持,请将 DatabaseFeatures.supports_over_clause 设置为 True。 您可能需要自定义 DatabaseOperations.window_start_rows_start_end() 和/或 window_start_range_start_end() 方法。
  • 第三方数据库后端应添加 DatabaseOperations.cast_char_field_without_max_length 属性,其数据库数据类型将在 Cast 函数中用于 CharField,如果 max_length未提供参数。
  • DatabaseCreation._clone_test_db()get_test_db_clone_settings() 的第一个参数现在是 suffix 而不是 number(以防您想重命名后端中的签名以保持一致性)。 django.test 现在也将这些值作为字符串而不是整数传递。
  • 第三方数据库后端应基于BaseDatabaseIntrospection中的存根添加DatabaseIntrospection.get_sequences()方法。


不再支持 Oracle 11.2

Oracle 11.2 上游支持的结束时间是 12 月。 2020. Django 1.11 将得到支持,直到 2020 年 4 月,几乎达到这个日期。 Django 2.0 正式支持 Oracle 12.1+。


默认 MySQL 隔离级别是已提交读

MySQL 的默认隔离级别,可重复读取,在典型的 Django 使用中可能会导致数据丢失。 为了防止这种情况并与其他数据库保持一致,默认隔离级别现在是读提交。 如果需要,您可以使用 :setting:`DATABASES` 设置来 使用不同的隔离级别


AbstractUser.last_name max_length increased to 150

包括 django.contrib.auth.models.User.last_name 的迁移。 如果您有一个从 AbstractUser 继承的自定义用户模型,则需要为您的用户模型生成并应用数据库迁移。

如果您想保留姓氏 30 个字符的限制,请使用自定义表单:

from django.contrib.auth.forms import UserChangeForm

class MyUserChangeForm(UserChangeForm):
    last_name = forms.CharField(max_length=30, required=False)

如果您希望在编辑用户时在 admin 中保留此限制,请设置 UserAdmin.form 以使用此表单:

from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User

class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm

admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

切片后禁止QuerySet.reverse()和last()

由于在重新排序后应用了切片,因此在切片查询集上调用 QuerySet.reverse()last() 会导致意外结果。 现在禁止这样做,例如:

>>> Model.objects.all()[:2].reverse()
Traceback (most recent call last):
...
TypeError: Cannot reverse a query once a slice has been taken.

表单字段不再接受可选参数作为位置参数

为了帮助防止由于表单字段参数的顺序不正确而导致的运行时错误,内置表单字段的可选参数不再被接受为位置参数。 例如:

forms.IntegerField(25, 10)

引发异常,应替换为:

forms.IntegerField(max_value=25, min_value=10)

call_command() 验证它收到的选项

call_command() 现在验证被调用命令的参数解析器定义了所有传递给 call_command() 的选项。

对于使用不是使用 parser.add_argument() 创建的选项的自定义管理命令,在命令上添加 stealth_options 属性:

class MyCommand(BaseCommand):
    stealth_options = ('option_name', ...)

索引不再接受位置参数

例如:

models.Index(['headline', '-pub_date'], 'index_name')

引发异常,应替换为:

models.Index(fields=['headline', '-pub_date'], name='index_name')

现在在 SQLite 上启用了外键约束

如果尝试保存违反外键约束的现有模型实例,这将显示为向后不兼容的更改 (IntegrityError: FOREIGN KEY constraint failed)。

现在使用 DEFERRABLE INITIALLY DEFERRED 而不是 DEFERRABLE IMMEDIATE 创建外键。 因此,可能需要重建表以使用新定义重新创建外键,特别是如果您使用这样的模式:

from django.db import transaction

with transaction.atomic():
    Book.objects.create(author_id=1)
    Author.objects.create(id=1)

如果您不将外键重新创建为 DEFERRED,那么由于强制执行外键约束,第一个 create() 将失败。

先备份你的数据库! 升级到 Django 2.0 后,您可以使用类似于此的脚本重建表:

from django.apps import apps
from django.db import connection

for app in apps.get_app_configs():
    for model in app.get_models(include_auto_created=True):
        if model._meta.managed and not (model._meta.proxy or model._meta.swapped):
            for base in model.__bases__:
                if hasattr(base, '_meta'):
                    base._meta.local_many_to_many = []
            model._meta.local_many_to_many = []
            with connection.schema_editor() as editor:
                editor._remake_table(model)

这个脚本没有经过广泛的测试,需要适应多种情况,比如多数据库。 随意贡献改进。

另外,由于SQLite的换表限制,禁止对事务中其他模型引用的模型或字段进行RenameModelRenameField操作。 为了允许应用包含这些操作的迁移,您必须将 Migration.atomic 属性设置为 False


杂项

  • SessionAuthenticationMiddleware 类被删除。 它没有提供任何功能,因为 Django 1.10 中无条件启用了会话身份验证。

  • 默认的 HTTP 错误处理程序(handler404 等)现在是可调用的,而不是带点的 Python 路径字符串。 Django 偏爱可调用引用,因为它们提供了更好的性能和调试体验。

  • 如果 pattern_name 不存在,RedirectView 不再使 NoReverseMatch 静音。

  • :setting:`USE_L10N` 关闭时,FloatFieldDecimalField 现在尊重 :setting:`DECIMAL_SEPARATOR`:设置:验证期间`THOUSAND_SEPARATOR`。 例如,使用设置:

    USE_L10N = False
    USE_THOUSAND_SEPARATOR = True
    DECIMAL_SEPARATOR = ','
    THOUSAND_SEPARATOR = '.'

    "1.345" 的输入现在转换为 1345 而不是 1.345

  • AbstractBaseUser 的子类不再需要实现 get_short_name()get_full_name()。 (引发 NotImplementedError 的基本实现被删除。)django.contrib.admin 使用这些方法(如果实现但不需要它们)。 使用这些方法的第三方应用程序可能希望采用类似的方法。

  • FIRST_DAY_OF_WEEKNUMBER_GROUPING 格式设置现在在 JavaScript 和 JSON i18n 视图输出中保留为整数。

  • assertNumQueries() 现在忽略连接配置查询。 以前,如果测试打开了一个新的数据库连接,这些查询可以作为 assertNumQueries() 计数的一部分包含在内。

  • Oracle 测试表空间的默认大小从 20M 增加到 50M,默认自动扩展大小从 10M 增加到 25M。

  • 为了提高从数据库流式传输大型结果集时的性能,QuerySet.iterator() 现在一次获取 2000 行而不是 100 行。 可以使用 chunk_size 参数恢复旧行为。 例如:

    Book.objects.iterator(chunk_size=100)
  • JavaScriptCatalog 视图的 packages 参数中提供未知的包名称现在会引发 ValueError 而不是静默传递。

  • 模型实例的主键现在出现在默认的 Model.__str__() 方法中,例如 Question object (1)

  • makemigrations 现在检测对模型字段 limit_choices_to 选项的更改。 将此添加到您现有的迁移或接受使用它的字段的自动生成的迁移。

  • 执行需要 自动空间变换 的查询现在在 MySQL 上引发 NotImplementedError,而不是静默使用未变换的几何图形。

  • django.core.exceptions.DjangoRuntimeWarning 被移除。 在CacheKeyWarningRuntimeWarning的继承中,它仅作为中间类用于缓存后端。

  • BaseExpression._output_field 重命名为 output_field。 您可能需要更新自定义表达式。

  • 在旧版本中,表单和表单集将它们的 Media 与小部件 Media 通过将两者连接起来。 组合现在尝试 保留每个列表 中元素的相对顺序。 MediaOrderConflictWarning

  • django.contrib.gis.gdal.OGRException 被移除。 自 Django 1.8 以来,它一直是 GDALException 的别名。

  • 不再支持 GEOS 3.3.x。

  • GeometryField 选择数据的方式已更改以提高性能,并且在原始 SQL 查询中,这些字段现在必须包含在 connection.ops.select 中。 有关示例,请参阅 GIS 教程中的 原始查询注释


2.0 中弃用的功能

Field.from_db_value() 和 Expression.convert_value() 的 context 参数

Field.from_db_value()Expression.convert_value()context 参数未使用,因为它始终是一个空字典。 这两种方法的签名现在是:

(self, value, expression, connection)

代替:

(self, value, expression, connection, context)

对自定义字段和表达式中旧签名的支持一直持续到 Django 3.0。


杂项

  • django.db.backends.postgresql_psycopg2 模块已弃用,取而代之的是 django.db.backends.postgresql。 自 Django 1.9 以来,它一直是别名。 这只会影响直接从模块导入的代码。 DATABASES 设置仍然可以使用 'django.db.backends.postgresql_psycopg2',但您可以使用 Django 1.9 中添加的 'django.db.backends.postgresql' 名称来简化它。
  • django.shortcuts.render_to_response() 已弃用,取而代之的是 django.shortcuts.render()render() 采用相同的参数,除了它还需要一个 request
  • DEFAULT_CONTENT_TYPE 设置已弃用。 它不能与第三方应用程序很好地交互并且已经过时,因为 HTML5 已经基本上取代了 XHTML。
  • HttpRequest.xreadlines() 已弃用,以支持对请求进行迭代。
  • QuerySet.earliest()QuerySet.latest()field_name 关键字参数已被弃用,以支持将字段名称作为参数传递。 写 .earliest('pub_date') 而不是 .earliest(field_name='pub_date')


2.0 中删除的功能

这些功能已达到弃用周期的终点,并在 Django 2.0 中删除。

有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅 1.9 中弃用的功能。

  • django.dispatch.signals.Signal.disconnect()weak 参数被删除。
  • django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() 被移除。
  • django.forms.extras 包被移除。
  • assignment_tag 助手被移除。
  • SimpleTestCase.assertsRedirects()host 参数被删除。 当路径相同时,允许将绝对 URL 视为等于相对 URL 的兼容性层也被删除。
  • Field.relField.remote_field.to 被移除。
  • ForeignKeyOneToOneFieldon_delete 参数现在在模型和迁移中是必需的。 考虑压缩迁移,以便更新更少的迁移。
  • django.db.models.fields.add_lazy_relation() 被移除。
  • 当启用时区支持时,当这些值作为参数传递给在 ORM 之外执行的 SQL 查询时,不支持时区的数据库后端不再将感知日期时间转换为 UTC 中的原始值,例如 cursor.execute()
  • django.contrib.auth.tests.utils.skipIfCustomUser() 被移除。
  • GeoManagerGeoQuerySet 类被删除。
  • django.contrib.gis.geoip 模块被移除。
  • 模板加载器的 supports_recursion 检查已从以下位置移除:
    • django.template.engine.Engine.find_template()
    • django.template.loader_tags.ExtendsNode.find_template()
    • django.template.loaders.base.Loader.supports_recursion()
    • django.template.loaders.cached.Loader.supports_recursion()
  • load_templateload_template_sources 模板加载器方法被删除。
  • 模板加载器的 template_dirs 参数被删除:
    • django.template.loaders.base.Loader.get_template()
    • django.template.loaders.cached.Loader.cache_key()
    • django.template.loaders.cached.Loader.get_template()
    • django.template.loaders.cached.Loader.get_template_sources()
    • django.template.loaders.filesystem.Loader.get_template_sources()
  • django.template.loaders.base.Loader.__call__() 被移除。
  • 删除了对不接受 exception 参数的自定义错误视图的支持。
  • django.utils.feedgenerator.Atom1Feeddjango.utils.feedgenerator.RssFeedmime_type属性被移除。
  • include()app_name 参数被删除。
  • 删除了将 3 元组(包括 admin.site.urls)作为第一个参数传递给 include() 的支持。
  • 删除了在没有应用程序命名空间的情况下设置 URL 实例命名空间的支持。
  • Field._get_val_from_obj() 被移除。
  • django.template.loaders.eggs.Loader 被移除。
  • 删除了 contrib.auth 基于函数的视图的 current_app 参数。
  • 删除了 SimpleTestCase.assertRaisesMessage()callable_obj 关键字参数。
  • 删除了对 ModelAdmin 方法上的 allow_tags 属性的支持。
  • 删除了 SyndicationFeed.add_item()enclosure 关键字参数。
  • django.template.base.Origindjango.template.loader.LoaderOrigindjango.template.base.StringOrigin 别名被删除。

有关这些更改的详细信息,请参阅 1.10 中弃用的 功能。

  • makemigrations --exit 选项被删除。
  • 删除了对直接分配给反向外键或多对多关系的支持。
  • 删除了 django.contrib.gis.geos.GEOSGeometryget_srid()set_srid() 方法。
  • get_x()set_x()get_y()set_y()get_z()set_z()方法django.contrib.gis.geos.Point ] 被删除。
  • 删除了 django.contrib.gis.geos.Pointget_coords()set_coords() 方法。
  • django.contrib.gis.geos.MultiPolygoncascaded_union 属性被移除。
  • django.utils.functional.allow_lazy() 被移除。
  • shell --plain 选项被删除。
  • django.core.urlresolvers 模块被移除以支持其新位置 django.urls
  • CommaSeparatedIntegerField 被移除,除了支持历史迁移。
  • 模板 Context.has_key() 方法被删除。
  • 删除了对 django.core.files.storage.Storage.accessed_time()created_time()modified_time() 方法的支持。
  • 删除了在设置 Meta.default_related_name 时使用模型名称进行查询查找的支持。
  • MySQL __search 查找被删除。
  • 删除了用于支持没有 _apply_rel_filters() 方法的自定义相关管理器类的垫片。
  • 不再支持使用 User.is_authenticated()User.is_anonymous() 作为方法而不是属性。
  • Model._meta.virtual_fields 属性被移除。
  • 删除了 Field.contribute_to_class() 中的关键字参数 virtual_onlyModel._meta.add_field() 中的 virtual
  • javascript_catalog()json_catalog() 视图被删除。
  • django.contrib.gis.utils.precision_wkt() 被移除。
  • 在多表继承中,删除了 OneToOneFieldparent_link 的隐式提升。
  • 删除了对 Widget._format_value() 的支持。
  • FileField 方法 get_directory_name()get_filename() 被删除。
  • mark_for_escaping() 函数及其使用的类:EscapeDataEscapeBytesEscapeTextEscapeStringEscapeUnicode移除。
  • escape 过滤器现在使用 django.utils.html.conditional_escape()
  • Manager.use_for_related_fields 被移除。
  • 模型Manager继承遵循MRO继承规则。 取消了使用 Meta.manager_inheritance_from_future 选择加入该行为的要求。
  • 删除了对使用 settings.MIDDLEWARE_CLASSES 的旧式中间件的支持。