Django 4.0于2021年12月正式发布,标志着Django 4.X时代的来临。参考Django 4.0 release notes | Django documentation | Django
Python 兼容性
Django 4.0 将支持 Python 3.8、3.9 与 3.10。强烈推荐并且仅官方支持每个系列的最新版本。
Django 3.2.x 系列是最后一个支持 Python 3.6 和 3.7 的。
Django 4.0 的新特性
Zoneinfo
成为默认时区
库
Python 标准库zoneinfo现在是 Django 中的默认时区实现。
这是从 usingpytz到 using 迁移的下一步zoneinfo。Django 3.2 允许使用非pytz时区,3.2是个过渡版本,可以使用非pytz的时区库。Django 4.0 是zoneinfo默认实现。支持pytz现在已弃用,将在 Django 5.0 中删除。
zoneinfo是 Python 3.9 中 Python 标准库的一部分。backports.zoneinfo如果使用的是 Python 3.8,该 软件包会自动与 Django 一起安装。
转向zoneinfo应该在很大程度上是透明的。当前时区的选择、日期时间实例到表单和模板中当前时区的转换以及对 UTC 中感知日期时间的操作不受影响。
但是,如果使用非 UTC 时区,并使用pytz normalize()和localize()API,可能与TIME_ZONE设置一起使用,将需要审核的代码,因为pytz 和zoneinfo不完全等效。
为了给这样的审计时间,过渡USE_DEPRECATED_PYTZ 设置允许pytz在 4.x 发布周期中继续使用。此设置将在 Django 5.0 中删除。
此外, 作者创建的pytz_deprecation_shim包zoneinfo可用于协助从pytz. 这个包提供了 shims 来帮助安全地移除pytz,并且有一个详细的 迁移指南展示了如何迁移到新的zoneinfoAPIs。
如果需要逐步更新路径,建议使用pytz_deprecation_shim和USE_DEPRECATED_PYTZ过渡设置。
基于这个变化django.utils.timezone.utc将变为datetime.timezone.utc。
功能唯一约束
新增*expressions 位置参数 UniqueConstraint()允许在表达式和数据库函数上创建功能唯一约束。例如:
from django.db import models
from django.db.models import UniqueConstraint
from django.db.models.functions import Lower
class MyModel(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
class Meta:
constraints = [
UniqueConstraint(
Lower('first_name'),
Lower('last_name').desc(),
name='first_last_name_unique',
),
]
使用该Meta.constraints选项将功能唯一约束添加到模型中 。
scrypt
密码哈希
新的scrypt 密码哈希算法比 PBKDF2 更安全,推荐使用。但是,它不是默认设置,因为它需要 OpenSSL 1.1+ 和更多内存。
新增Redis 缓存后端
以前Django中使用redis都要安装django_redis,并将第三方库提供的django_redis.cache.RedisCache设置作为缓存后端。新版本内置了django.core.cache.backends.redis.RedisCache缓存后端,为使用 Redis 进行缓存提供了内置支持。需要 redis-py 3.0.0 或更高版本。有关更多详细信息,请参阅Django 中使用 Redis 进行缓存的文档。
基于模板的表单渲染
Forms, Formsets , 并且ErrorList现在使用模板引擎呈现以增强自定义。看到新的render(), get_context()以及 template_name用于Form和 表单集渲染了Formset。
次要功能
django.contrib.admin
- 该admin/base.html模板现在有一个header包含管理站点标题的新块。
- 新ModelAdmin.get_formset_kwargs()方法允许自定义传递给表单集构造函数的关键字参数。
- 导航侧边栏现在有一个快速过滤工具栏。
- model包含每个模型的模型类的新上下文变量被添加到AdminSite.each_context()方法中。
- 新ModelAdmin.search_help_text属性允许为搜索框指定描述性文本。
- 该InlineModelAdmin.verbose_name_plural属性现在回退到InlineModelAdmin.verbose_name+ 's'。
- jQuery 从 3.5.1 升级到 3.6.0。
django.contrib.admindocs
- admindocs 现在允许在ROOT_URLCONF不是字符串的情况下进行深奥的设置。
- 现在的模型部分admindocs显示缓存的属性。
django.contrib.auth
- PBKDF2 密码哈希的默认迭代次数从 260,000 增加到 320,000。
- 新的 LoginView.next_page 属性和 get_default_redirect_url()方法允许在登录后自定义重定向。
django.contrib.gis
- 添加了对 SpatiaLite 5 的支持。
- GDALRaster 现在允许在任何 GDAL 虚拟文件系统中创建栅格。
- 新GISModelAdmin类允许自定义用于GeometryField. 这是鼓励而不是弃用的GeoModelAdminand OSMGeoAdmin。
django.contrib.postgres
- PostgreSQL 后端现在支持通过服务名称进行连接。有关更多详细信息,请参阅 PostgreSQL 连接设置。
- 新AddConstraintNotValid 操作允许在 PostgreSQL 上创建检查约束,而无需验证所有现有行是否满足新约束。
- 新ValidateConstraint 操作允许验证AddConstraintNotValid在 PostgreSQL 上创建的检查约束 。
- 新 ArraySubquery() 表达式允许使用子查询在 PostgreSQL 上构造值列表。
- 新的trigram_word_similar查找和 TrigramWordDistance()and TrigramWordSimilarity()表达式允许使用三元词相似度。
django.contrib.staticfiles
- ManifestStaticFilesStorage 现在用它们的散列对应物替换 JavaScript 源映射引用的路径。
- 的新manifest_storage参数 ManifestFilesMixinand ManifestStaticFilesStorage 允许自定义清单文件存储。
缓存
- 新的异步 APIdjango.core.cache.backends.base.BaseCache开始了使缓存后端异步兼容的过程。新的异步方法都有a前缀名称,例如aadd(), aget(), aset(), aget_or_set(), 或adelete_many().
展望未来,a前缀通常用于方法的异步变体。
CSRF
- CSRF 保护现在会参考Origin标头(如果存在)。为此,需要对 设置进行一些更改CSRF_TRUSTED_ORIGINS。
表格
- ModelChoiceField现在在为 错误消息params引发的参数中 包含提供的值。这允许自定义错误消息使用 占位符。ValidationErrorinvalid_choice%(value)s
- BaseFormSet现在使用额外的类呈现非表单错误,nonform以帮助将它们与特定于表单的错误区分开来。
- BaseFormSet现在允许can_delete通过设置 deletion_widget属性或覆盖get_deletion_widget() 方法来自定义删除表单时使用的小部件 。
国际化
- 添加了对马来语的支持和翻译。
通用视图
- DeleteView现在使用 FormMixin,允许提供一个 Form子类,例如一个复选框,以确认删除。此外,这允许DeleteView使用 django.contrib.messages.views.SuccessMessageMixin.
根据FormMixin,POST 请求的对象删除是在 中处理的form_valid()。delete()应根据需要将处理程序中的自定义删除逻辑移至form_valid()或共享辅助方法。
日志记录
- SQL 调用中使用的数据库的别名现在作为额外的上下文与每条消息一起传递给django.db.backends记录器。
管理命令
- 该runserver管理命令现在支持 --skip-checks选项。
- 在 PostgreSQL 上,dbshell现在支持指定密码文件。
- 该shell命令现在sys.__interactivehook__ 在启动时尊重。这允许在交互式会话之间加载 shell 历史记录。因此,readline如果在隔离 模式下运行,则不再加载。
- 新BaseCommand.suppressed_base_arguments属性允许在帮助输出中抑制不受支持的默认命令选项。
- 新的和 选项允许从模板中排除目录。startapp
模型
- 新QuerySet.contains(obj)方法,返回查询集是否包含给定对象。这试图以最简单和最快的方式执行查询。
- 数据库函数的新precision参数 Round()允许指定舍入后的小数位数。
- QuerySet.bulk_create() 现在在使用 SQLite 3.35+ 时设置对象的主键。
- DurationField 现在支持 SQLite 上的标量值乘除。
- QuerySet.bulk_update() 现在返回更新的对象数。
- Expression.empty_result_set_value当函数用于空结果集时,新属性允许指定要返回的值。
- MariaDB 10.6+ 现在允许使用的skip_locked参数QuerySet.select_for_update()。
- Lookup表达式现在可以在QuerySet 注释、聚合中使用,也可以直接在过滤器中使用。
- 内置聚合的新默认参数允许指定在查询集(或分组)不包含条目时返回的值,而不是None.
请求和响应
- 在SecurityMiddleware现在增加了 跨来源开瓶器策略标头的值'same-origin',以防止交叉起源弹出窗口共享同一浏览器上下文。可以通过将SECURE_CROSS_ORIGIN_OPENER_POLICY设置设置为来防止添加此标头None。
信号
- 和信号的新stdout参数允许将输出重定向到类似流的对象。应当优于并以允许适当的捕获测试时发光详细的输出时。pre_migrate()post_migrate()sys.stdoutprint()
模板
- floatformat模板过滤器现在允许使用u后缀来强制禁用本地化。
测试
- 的新serialized_aliases参数 django.test.utils.setup_databases()确定哪些 DATABASES别名测试数据库应将其状态序列化以允许使用 serialized_rollback功能。
- Django 测试运行器现在支持--buffer带有并行测试的选项。
- 的新logger参数DiscoverRunner 允许使用 Python记录器进行记录。
- 新DiscoverRunner.log()方法提供了一种记录消息的方法,DiscoverRunner.logger如果未设置,则使用, 或打印到控制台。
- Django 测试运行器现在支持--shuffle以随机顺序执行测试的选项。
- 该选项现在支持为每个处理器内核运行一个测试进程的值。test
- TestCase.captureOnCommitCallbacks()现在捕获执行transaction.on_commit()回调时添加的新回调。
4.0 中向后不兼容的更改
数据库后端 API
本节介绍第三方数据库后端可能需要的更改。
- DatabaseOperations.year_lookup_bounds_for_date_field()和 year_lookup_bounds_for_datetime_field()方法现在采用可选 iso_year参数以支持 ISO-8601 周编号年份的界限。
- DatabaseSchemaEditor._unique_sql()和 _create_unique_sql()方法的第二个参数现在fields代替columns.
django.contrib.gis
- 删除了对 PostGIS 2.3 的支持。
- 删除了对 GDAL 2.0 和 GEOS 3.5 的支持。
放弃对 PostgreSQL 9.6 的支持
对 PostgreSQL 9.6 的上游支持将于 2021 年 11 月结束。Django 4.0 支持 PostgreSQL 10 及更高版本。
此外,支持的最低版本psycopg2从 2.5.4 增加到 2.8.4,因为psycopg22.8.4 是第一个支持 Python 3.8 的版本。
放弃对 Oracle 12.2 和 18c 的支持
对 Oracle 12.2 的上游支持将于 2022 年 3 月结束,对 Oracle 18c 的上游支持将于 2021 年 6 月结束。Django 3.2 将支持到 2024 年 4 月。Django 4.0 正式支持 Oracle 19c。
CSRF_TRUSTED_ORIGINS变化
格式更改
CSRF_TRUSTED_ORIGINS设置中的值必须包括方案(例如'http://'或'https://')而不仅仅是主机名。
此外,以点开头的值现在还必须在点之前包含一个星号。例如,更改'.example.com'为'https://*.example.com'.
系统检查会检测任何所需的更改。
现在可能需要配置它
由于 CSRF 保护现在会参考Origin标头,因此可能需要设置 CSRF_TRUSTED_ORIGINS,特别是如果通过设置CSRF_COOKIE_DOMAIN(或 SESSION_COOKIE_DOMAIN如果CSRF_USE_SESSIONS启用)以点开头的值来允许来自子域的请求。
SecurityMiddleware不再设置X-XSS-Protection标题
将SecurityMiddleware不再设置 X-XSS-Protection标题,如果SECURE_BROWSER_XSS_FILTER设置 True。该设置被删除。
大多数现代浏览器不支持X-XSS-ProtectionHTTP 标头。可以使用Content-Security-Policy而不允许使用'unsafe-inline'脚本。
如果想支持旧版浏览器并设置标头,请在自定义中间件中使用此行:
response.headers.setdefault('X-XSS-Protection', '1; mode=block')
迁移自动检测器更改
迁移自动检测器现在使用模型状态而不是模型类。此外,ForeignKey和ManyToManyField字段的迁移操作不再指定在初始化期间未传递给字段的属性。
作为副作用,在某些情况下,运行makemigrations可能会AlterField为ManyToManyField和ForeignKey字段生成无操作 操作。
DeleteView变化
DeleteView现在用于 FormMixin处理 POST 请求。因此,如果需要,delete()应将处理程序中的任何自定义删除逻辑移至form_valid()或共享辅助方法。
杂项
- cx_Oracle删除了对< 7.0 的支持。
- 为了允许在不更改 值的情况下在子路径上提供 Django 站点, STATIC_URL从'static/'默认startproject模板中的该设置(现在)中删除了前导斜杠 。
- AdminSite管理index 视图的方法never_cache在直接访问时不再被修饰,而不是通过推荐的AdminSite.urls属性或 AdminSite.get_urls()方法。
- 切片查询集上不受支持的操作现在引发TypeError而不是AssertionError.
- 未记录的django.test.runner.reorder_suite()函数重命名为reorder_tests(). 它现在接受一个可迭代的测试而不是一个测试套件,并返回一个测试的迭代器。
- 调用FileSystemStorage.delete()与空name现在提出 ValueError来代替AssertionError。
- 使用无效的or 参数调用EmailMultiAlternatives.attach_alternative()or 现在 raise而不是.EmailMessage.attach()contentmimetypeValueErrorAssertionError
- assertHTMLEqual() 不再考虑没有值的非布尔属性等于具有相同名称和值的属性。
- 无法加载的测试(例如由于语法错误)现在在使用.test
- 未记录的django.contrib.admin.utils.lookup_needs_distinct() 函数重命名为lookup_spawns_duplicates().
- 未记录的HttpRequest.get_raw_uri()方法被删除。该 HttpRequest.build_absolute_uri()方法可以是合适的替代方案。
- objectundocumented ModelAdmin.log_addition()、 log_change()和log_deletion()methods的参数重命名为obj。
- RssFeed, Atom1Feed, 及其子类现在发出没有内容的元素作为自闭合标签。
- NodeList.render()不再将render()单个节点的方法输出转换为字符串。Node.render()应始终返回记录的字符串。
- 在where_class财产django.db.models.sql.query.Query和 where_class参数的私有get_extra_restriction()方法 ForeignObject和ForeignObjectRel将被删除。如果需要,请django.db.models.sql.where.WhereNode改为初始化 。
- filter_clause未记录Query.add_filter() 方法的参数被两个位置参数filter_lhs和 filter_rhs.
- CsrfViewMiddleware现在使用 request.META['CSRF_COOKIE_NEEDS_UPDATE']的地方 request.META['CSRF_COOKIE_USED'],request.csrf_cookie_needs_reset以及response.csrf_cookie_set跟踪CSRF cookie是否应该被发送。这是一个未记录的私有 API。
- 未记录的TRANSLATOR_COMMENT_MARK常量从 django.template.base移至django.utils.translation.template。
- 如果提供real_apps,未记录django.db.migrations.state.ProjectState.__init__()方法的参数 现在必须是一个集合。
- RadioSelect和 CheckboxSelectMultiple小部件,现在呈现在 <div>代码,以便它们公布更简洁的屏幕阅读器。如果需要前面的行为,请使用 Django 3.2 中的适当模板覆盖小部件模板。
- 该floatformat模板过滤器不再依赖于 USE_L10N环境,并始终返回本地化输出。使用u 后缀禁用本地化。
- 设置的默认值USE_L10N更改为True。有关更多详细信息,请参阅上面的 本地化部分。
- 作为迁移到 zoneinfo 的一部分, django.utils.timezone.utc更改为 alias datetime.timezone.utc。
- 支持的最低版本asgiref从 3.3.2 增加到 3.4.1。
4.0 中弃用的功能
pytz时区的使用
作为迁移到 zoneinfo 的一部分,pytz不推荐使用时区。
因此,以下is_dst论点也被弃用:
- django.db.models.query.QuerySet.datetimes()
- django.db.models.functions.Trunc()
- django.db.models.functions.TruncSecond()
- django.db.models.functions.TruncMinute()
- django.db.models.functions.TruncHour()
- django.db.models.functions.TruncDay()
- django.db.models.functions.TruncWeek()
- django.db.models.functions.TruncMonth()
- django.db.models.functions.TruncQuarter()
- django.db.models.functions.TruncYear()
- django.utils.timezone.make_aware()
pytz在 Django 5.0 中将删除对使用的支持。
时区支持
为了遵循良好的实践,在 Django 5.0中,USE_TZ 设置的默认值将从 更改False为True,并且默认启用时区支持。
请注意,自 Django 1.4 以来settings.py由包含 创建的默认文件 。django-admin
startprojectUSE_TZ
=
True
可以设置USE_TZ到False的项目设置,在此之前选择退出。
本地化
为了遵循良好的做法,USE_L10N设置的默认值从 更改False为True。
此外USE_L10N,在此版本中已弃用。从 Django 5.0 开始,默认情况下,Django 显示的任何日期或数字都将被本地化。
该标签和/ 过滤器仍然会被Django的荣幸。{%
localize
%}localizeunlocalize
杂项
- SERIALIZE测试设置已被弃用,因为它可以从推断 databases与 serialized_rollback选项启用。
- 未记录的django.utils.baseconv模块已弃用。
- 未记录的django.utils.datetime_safe模块已弃用。
- 在 Django 5.0 中'http','https'在请求上下文之外构建的站点地图的默认站点地图协议将从 更改为。
- 在extra_tests对参数DiscoverRunner.build_suite()和 DiscoverRunner.run_tests()已经过时了。
- 的ArrayAgg, JSONBAgg和 StringAgg聚集将返回 None时没有行代替[],[]以及'' 分别在Django 5.0。如果需要以前的行为,明确设置 default到Value([]),Value('[]')或Value('')。
- 在django.contrib.gis.admin.GeoModelAdmin和OSMGeoAdmin类弃用。使用ModelAdminand GISModelAdmin代替。
- 由于表单渲染现在使用模板引擎,因此BaseForm._html_output()不推荐使用未记录的 辅助方法。
- str从ErrorListand返回 a 的能力ErrorDict已被弃用。预计这些方法会返回一个SafeString.
4.0 中删除的功能
这些特性已经到了弃用周期的尾声,并在 Django 4.0 中被删除。
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅3.0 中弃用的功能。
- django.utils.http.urlquote(), urlquote_plus(),urlunquote()和 urlunquote_plus()被删除。
- django.utils.encoding.force_text()并被smart_text()移除。
- django.utils.translation.ugettext(), ugettext_lazy(), ugettext_noop(), ungettext(), 和ungettext_lazy()被删除。
- django.views.i18n.set_language()未在request.session(key _language) 中设置用户语言 。
- alias=None在django.db.models.Expression.get_group_by_cols()子类的签名中是必需的 。
- django.utils.text.unescape_entities() 已移除。
- django.utils.http.is_safe_url() 已移除。
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅3.1 中弃用的功能。
- 该PASSWORD_RESET_TIMEOUT_DAYS设置被删除。
- 所述isnull查找不再允许使用非布尔值作为右侧。
- 该django.db.models.query_utils.InvalidQuery异常类被删除。
- 该django-admin.py入口点被删除。
- 该HttpRequest.is_ajax()方法被删除。
- django.contrib.messages.storage.cookie.CookieStorage删除了对 Django 3.1 之前使用的 cookie 值编码格式的支持 。
- 删除了对管理站点(使用 SHA-1 散列算法)中的 Django 3.1 之前的密码重置令牌的支持。
- 删除了对会话的 pre-Django 3.1 编码格式的支持。
- django.core.signing.Signer删除了对Django 3.1 之前的签名(使用 SHA-1 算法编码)的支持。
- 删除了对 Django 3.1 之前的django.core.signing.dumps()签名(使用 SHA-1 算法编码)的支持django.core.signing.loads()。
- 删除了对 Django 3.1 之前的用户会话(使用 SHA-1 算法)的支持。
- 在get_response为参数 django.utils.deprecation.MiddlewareMixin.__init__()需要的是,不接受None。
- providing_argsfor的参数django.dispatch.Signal被删除。
- lengthfor的参数django.utils.crypto.get_random_string()是必需的。
- 的list消息ModelMultipleChoiceField被删除。
- QuerySet.order_by()删除了对传递原始列别名的支持。
- 该NullBooleanField模型字段被删除,除了在历史迁移的支持。
- django.conf.urls.url() 已移除。
- 该django.contrib.postgres.fields.JSONField模型字段被删除,除了在历史迁移的支持。
- django.contrib.postgres.fields.jsonb.KeyTransform并被 django.contrib.postgres.fields.jsonb.KeyTextTransform移除。
- django.contrib.postgres.forms.JSONField 已移除。
- {%
该DEFAULT_HASHING_ALGORITHM过渡设置将被删除。