December 7, 2021
欢迎来到Django 4.0!
这些发行说明涵盖 new features ,以及一些 backwards incompatible changes 从Django 3.2或更早版本升级时您需要注意这一点。我们 begun the deprecation process for some features 。
见 如何将Django升级到更新版本 如果正在更新现有项目,则提供指南。
Django 4.0支持Python 3.8、3.9和3.10。我们 highly recommend 并且仅官方支持每个系列的最新版本。
Django 3.2.x系列是最后一个支持Python3.6和3.7的版本。
zoneinfo 默认时区实施¶Python标准库的 zoneinfo 现在是Django中的默认时区实现。
这是从使用迁移的下一步 pytz 到使用 zoneinfo 。Django 3.2允许使用非`pytz`时区。Django 4.0使 zoneinfo 默认实现。支持 pytz 现在已弃用,将在Django 5.0中删除。
zoneinfo 是来自Python3.9的Python标准库的一部分。这个 backports.zoneinfo 如果您使用的是Python3.8,包将自动与Django一起安装。
迁移到 zoneinfo 应该在很大程度上透明。在表单和模板中选择当前时区、将DateTime实例转换为当前时区以及在UTC中对Aware DateTime执行的操作不受影响。
但是,如果您正在使用非UTC时区,并且使用 pytz normalize() 和 localize() API,可能使用 TIME_ZONE 设置时,您将需要审核代码,因为 pytz 和 zoneinfo 并不完全等同。
为了给这样的审计留出时间,过渡时期的 USE_DEPRECATED_PYTZ 设置允许继续使用 pytz 在4.x版本周期内。此设置将在Django 5.0中删除。
此外,a pytz_deprecation_shim 包,由 zoneinfo 作者,可用于帮助从 pytz 。此程序包提供垫片,以帮助您安全地删除 pytz ,并有详细的 migration guide 展示如何迁移到新的 zoneinfo API接口。
vbl.使用 pytz_deprecation_shim 以及 USE_DEPRECATED_PYTZ 如果您需要渐进式更新路径,建议使用过渡设置。
新的 *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 password hasher 比PBKDF2更安全,推荐使用。然而,它不是默认的,因为它需要OpenSSL1.1+和更大的内存。
新的 django.core.cache.backends.redis.RedisCache 缓存后端内置Redis缓存支持。 redis-py 需要3.0.0或更高版本。有关更多详细信息,请参阅 documentation on caching with Redis in Django 。
Forms , Formsets ,以及 ErrorList 现在使用模板引擎呈现,以增强定制。请看新的 render() , get_context() ,以及 template_name 为 Form 和 formset rendering 为 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¶管理员现在允许在以下情况下进行深奥的设置 ROOT_URLCONF 不是字符串。
的模型部分 admindocs 现在显示缓存的属性。
django.contrib.auth¶PBKDF 2密码哈希器的默认迭代计数从260,000增加到320,000。
新的 LoginView.next_page 属性和 get_default_redirect_url() 方法允许在登录后自定义重定向。
django.contrib.gis¶添加了对SpatiaLite 5的支持。
GDALRaster 现在允许在任何GDAL虚拟文件系统中创建栅格。
新的 GISModelAdmin 类允许自定义用于 GeometryField 。这是鼓励而不是弃用的 GeoModelAdmin 和 OSMGeoAdmin 。
django.contrib.postgres¶PostgreSQL后台现在支持通过服务名称连接。看到 PostgreSQL连接设置 了解更多详细信息。
新的 AddConstraintNotValid 操作允许在不验证所有现有行是否满足新约束的情况下在PostgreSQL上创建检查约束。
新的 ValidateConstraint 操作允许验证使用以下命令创建的检查约束 AddConstraintNotValid 在PostgreSQL上。
新的 ArraySubquery() 表达式允许使用子查询在PostgreSQL上构建值列表。
新的 trigram_word_similar 查找,以及 TrigramWordDistance() 和 TrigramWordSimilarity() 表达式允许使用三元组单词相似度。
django.contrib.staticfiles¶ManifestStaticFilesStorage 现在使用其哈希对应项替换指向JavaScript源映射引用的路径。
新的 manifest_storage 的论点 ManifestFilesMixin 和 ManifestStaticFilesStorage 允许自定义清单文件存储。
新的异步API用于 django.core.cache.backends.base.BaseCache 开始使缓存后端与异步兼容的过程。新的异步方法都有 a 带有前缀的名称,例如 aadd() , aget() , aset() , aget_or_set() ,或 adelete_many() 。
展望未来, a 前缀通常用于方法的异步变体。
CSRF保护现在咨询 Origin 标题(如果存在)。为了促进这一点, some changes 发送到 CSRF_TRUSTED_ORIGINS 设置是必需的。
ModelChoiceField 现在将提供的值包括在 params 提出的论点 ValidationError 对于 invalid_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 如果在其中运行,则不再加载 isolated 模式。
新的 BaseCommand.suppressed_base_arguments 属性允许取消帮助输出中不受支持的默认命令选项。
新的 startapp --exclude 和 startproject --exclude 选项允许从模板中排除目录。
新的 QuerySet.contains(obj) 方法返回查询集是否包含给定对象。这会尝试以最简单、最快的方式执行查询。
新的 precision 的论据 Round() 数据库功能允许指定四舍五入后的小数位数。
QuerySet.bulk_create() 现在使用SQLite 3.35+时设置对象的主键。
DurationField 现在支持在SQLite上按标量值乘除。
QuerySet.bulk_update() 现在返回更新的对象数。
新的 Expression.empty_result_set_value 属性允许指定在对空结果集使用函数时要返回的值。
这个 skip_locked 的论点 QuerySet.select_for_update() 现在在MariaDB 10.6+上允许。
Lookup 现在可以在以下位置使用表达式 QuerySet 注释、聚合和直接在筛选器中。
新的 default 内置聚合的参数允许在查询集(或分组)不包含条目时指定要返回的值,而不是 None 。
这个 SecurityMiddleware 现在添加了 Cross-Origin Opener Policy 值为的标头 'same-origin' 以防止跨域弹出窗口共享相同的浏览上下文。属性可以防止添加此标头 SECURE_CROSS_ORIGIN_OPENER_POLICY 设置为 None 。
新的 stdout 论据 pre_migrate() 和 post_migrate() Signals允许将输出重定向到类似流的对象。它应该比它更好 sys.stdout 和 print() 当发出详细输出时,以允许在测试时正确捕获。
floatformat 模板筛选器现在允许使用 u 用于强制禁用本地化的后缀。
新的 serialized_aliases 的论点 django.test.utils.setup_databases() 确定哪一个 DATABASES 别名测试数据库应将其状态序列化,以允许使用 serialized_rollback 特写。
这个 test --buffer 选项现在支持并行测试。
新的 logger 参数为 DiscoverRunner 允许使用一条 Python logger 用于日志记录。
新的 DiscoverRunner.log() 方法提供了一种记录使用 DiscoverRunner.logger ,或在未设置的情况下打印到控制台。
DiscoverRunner 现在可以按随机顺序使用 test --shuffle 选择。
这个 test --parallel 选项现在支持该值 auto 为每个处理器核心运行一个测试进程。
TestCase.captureOnCommitCallbacks() 现在捕获在执行时添加的新回调 transaction.on_commit() 回电。
本节描述第三方数据库后端可能需要的更改。
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的上游支持将于2021年11月结束。Django 4.0支持PostgreSQL 10及更高版本。
此外,受支持的最低版本 psycopg2 从2.5.4增加到2.8.4,因为 psycopg2 2.8.4是第一个支持Python3.8的版本。
对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-Protection HTTP标头。您可以使用 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() ,或共享帮助器方法(如果需要)。
Django 4.0无意中更改了Oracle上的表和列命名方案。这会导致名称长度超过30个字符的模型和字段出错。遗憾的是,需要重命名一些Oracle表和列。使用中的升级脚本 33789 生成 RENAME 更改命名方案的语句。
支持 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 。
叫唤 EmailMultiAlternatives.attach_alternative() 或 EmailMessage.attach() 带有无效的 content 或 mimetype 现在引起了争论 ValueError 而不是 AssertionError 。
assertHTMLEqual() 不再将值不等于具有相同名称和值的属性的非布尔属性视为。
无法加载的测试(例如,由于语法错误)现在在使用 test --tag 。
未登记的人 django.contrib.admin.utils.lookup_needs_distinct() 函数已重命名为 lookup_spawns_duplicates() 。
未登记的人 HttpRequest.get_raw_uri() 方法被移除。这个 HttpRequest.build_absolute_uri() 方法可能是一种合适的替代方法。
这个 object 无证之辩 ModelAdmin.log_addition() , log_change() ,以及 log_deletion() 方法被重命名为 obj 。
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> 标记,这样屏幕阅读器就可以更简洁地通知它们。如果您需要先前的行为, override the widget template 使用Django 3.2中的适当模板。
这个 floatformat 模板筛选器不再依赖 USE_L10N 设置并始终返回本地化输出。使用 u 后缀以禁用本地化。
的缺省值 USE_L10N 设置更改为 True 。请参阅 Localization section 有关更多详细信息,请参见上文。
作为该计划的一部分 move to zoneinfo , django.utils.timezone.utc 更改为别名 datetime.timezone.utc 。
支持的最低版本 asgiref 从3.3.2增加到3.4.1。
pytz 时区¶作为该计划的一部分 move to zoneinfo ,使用 pytz 时区已弃用。
因此, is_dst 也不建议使用以下参数:
支持使用 pytz 将在Django 5.0中删除。
为了遵循良好做法, USE_TZ 设置将从 False 至 True ,在Django 5.0中默认会启用时区支持。
请注意,默认设置为 settings.py 文件创建者 django-admin startproject 包括 USE_TZ = True 从Django 1.4开始。
您可以设置 USE_TZ 至 False 在此之前在您的项目设置中选择退出。
为了遵循良好做法, USE_L10N 设置更改自 False 至 True 。
更有甚者 USE_L10N 自本版本起不再推荐使用。从Django 5.0开始,默认情况下,Django显示的任何日期或数字都将被本地化。
这个 {% localize %} 标记和 localize / unlocalize Django仍然会尊重Filters。
SERIALIZE 测试设置已弃用,因为它可以从 databases 与 serialized_rollback 选项已启用。
未登记的人 django.utils.baseconv 模块已弃用。
未登记的人 django.utils.datetime_safe 模块已弃用。
在请求上下文之外构建的站点地图的默认站点地图协议将从 'http' 至 'https' 在Django 5.0中。
这个 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 类已弃用。使用 ModelAdmin 和 GISModelAdmin 取而代之的是。
由于表单呈现现在使用模板引擎,因此未记录的 BaseForm._html_output() 帮助器方法已弃用。
能够返回一个 str 从… ErrorList 和 ErrorDict 已弃用。预计这些方法将返回 SafeString 。
这些功能已达到弃用周期的末尾,并在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 (关键 _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 3.1之前使用的cookie值编码格式 django.contrib.messages.storage.cookie.CookieStorage 被移除。
管理站点(使用SHA-1哈希算法)中对Django 3.1之前密码重置令牌的支持已删除。
删除了对Django 3.1之前的会话编码格式的支持。
对Django 3.1之前的支持 django.core.signing.Signer 签名(使用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_args 论据 django.dispatch.Signal 被移除。
这个 length 论据 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 被移除。
这个 {% ifequal %} 和 {% ifnotequal %} 模板标签被删除。
这个 DEFAULT_HASHING_ALGORITHM 已删除过渡设置。
5月 28, 2025