2024 年 8 月 7 日
欢迎使用 Django 5.1!
这些发布说明涵盖了 新功能,以及从 Django 5.0 或更早版本升级时应注意的一些 不兼容的更改。我们已经 开始对一些功能进行弃用处理。
如果你要更新现有的项目,请看 如何将 Django 更新至新的版本 指南。
Django 5.1 支持 Python 3.10、3.11、3.12 和 3.13(截至 5.1.3)。我们 强烈建议 并且仅官方支持每个系列的最新版本。
{% querystring %} 模版标签¶Django 5.1 引入了 {% querystring %} 模板标签,简化了 URL 中查询参数的修改,使得生成在添加或更改特定参数的同时保持现有查询参数的链接变得更加容易。
例如,在模板中处理分页和查询字符串可能会很繁琐。考虑以下模板片段,它动态生成了一个用于在分页视图中导航到下一页的 URL:
{# Linebreaks added for readability, this should be one, long line. #}
<a href="?{% for key, values in request.GET.iterlists %}
{% if key != "page" %}
{% for value in values %}
{{ key }}={{ value }}&
{% endfor %}
{% endif %}
{% endfor %}page={{ page.next_page_number }}">Next page</a>
当切换到使用这个新的模板标签时,上面的代码神奇地变成了:
<a href="{% querystring page=page.next_page_number %}">Next page</a>
Django 5.1 还引入了对 PostgreSQL 的 连接池 支持。由于建立新连接的时间可能相对较长,保持连接打开可以减少延迟。
要使用 psycopg 的连接池,你可以在 OPTIONS 中将 "pool" 选项设置为一个字典,传递给 ConnectionPool,或者设置为 True 以使用 ConnectionPool 的默认值:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
# ...
"OPTIONS": {
"pool": {
"min_size": 2,
"max_size": 4,
"timeout": 10,
}
},
},
}
新的 LoginRequiredMiddleware 将所有未经身份验证的请求重定向到登录页面。视图可以使用新的 login_not_required() 装饰器来允许未经身份验证的请求。
LoginRequiredMiddleware 尊重通过 login_required() 装饰器设置的 login_url 和 redirect_field_name 值,但不支持通过 LoginRequiredMixin 设置 login_url 或 redirect_field_name。
要启用此功能,请将 "django.contrib.auth.middleware.LoginRequiredMiddleware" 添加到你的 MIDDLEWARE 设置中。
django.contrib.admin¶ModelAdmin.list_display 现在支持使用 __ 查找来列出相关模型的字段。
django.contrib.auth¶PBKDF2 密码哈希器的默认迭代次数从 720,000 增加到 870,000。
ScryptPasswordHasher 的默认 parallelism 从 1 增加到 5,以遵循 OWASP 的建议。
新的 AdminUserCreationForm 和现有的 AdminPasswordChangeForm 现在支持通过在表单保存时设置不可用密码来禁用基于密码的身份验证。现在在访问用户创建和密码更改页面时,管理界面中也提供了此功能。
login_required()、permission_required() 和 user_passes_test() 装饰器现在支持包装异步视图函数。
ReadOnlyPasswordHashWidget 现在包含一个重置用户密码的按钮,取代了之前嵌入在 ReadOnlyPasswordHashField 帮助文本中的链接,从而提高了 UserChangeForm 的整体可访问性。
django.contrib.gis¶BoundingCircle 现在在 SpatiaLite 5.1+ 上受支持。
Collect 现在在 MySQL 8.0.24+ 上受支持。
GeoIP2 现在允许使用 ipaddress.IPv4Address 或 ipaddress.IPv6Address 对象进行查询。
GeoIP2.country() 现在暴露了 continent_code、continent_name 和 is_in_european_union 值。
GeoIP2.city() 现在暴露了 accuracy_radius 和 region_name 值。此外,dma_code 和 region 值现在分别暴露为 metro_code 和 region_code,但为了向后兼容,之前的键仍然保留。
Area 现在支持 ha 单位。
新的 OGRGeometry.is_3d 属性允许检查几何体是否具有 Z 坐标维度。
新的 OGRGeometry.set_3d() 方法允许添加和移除 Z 坐标维度。
OGRGeometry、Point、LineString、Polygon 和 GeometryCollection 及其子类现在通过新的 OGRGeometry.is_measured 和 m 属性以及 OGRGeometry.set_measured() 方法支持测量几何体。
OGRGeometry.centroid 现在在所有支持的几何体类型上都可用。
django.contrib.postgres¶BTreeIndex 现在支持 deduplicate_items 参数。
django.contrib.sessions¶django.contrib.sessions.backends.cached_db.SessionStore 现在处理在缓存中存储会话信息时的异常,通过新添加的 sessions logger 记录适当的错误信息及其回溯。
django.contrib.sessions.backends.base.SessionBase 和所有内置的会话引擎现在提供了异步 API。新的异步方法都以 a 前缀命名,例如 aget()、akeys() 或 acycle_key()。
"init_command" 选项现在在 SQLite 的 OPTIONS 中受支持,允许指定在连接时设置的 pragma options。
"pool" 选项现在在 PostgreSQL 的 OPTIONS 中受支持,允许使用 connection pools。
为了提高可访问性,技术性的 404 和 500 错误页面现在对页眉、页脚和主要内容区域使用 HTML 地标元素。
FileSystemStorage 的 allow_overwrite 参数现在允许将新文件保存到现有文件上。
为了提高可访问性并使屏幕阅读器能够将字段集与其帮助文本关联起来,表单字段集现在包含 aria-describedby HTML 属性。
makemigrations 命令现在为每个操作显示有意义的符号,以突出显示 操作类别。
新的 Operation.category 属性允许指定 makemigrations 使用的 操作类别,以便为操作显示有意义的符号。
QuerySet.explain() 现在在 PostgreSQL 16+ 上支持 generic_plan 选项。
RowRange 现在接受 start 参数的正整数和 end 参数的负整数。
RowRange 和 ValueRange 的新 exclusion 参数允许从窗口框架中排除行、组和并列项。
QuerySet.order_by() 现在支持通过注解转换(如 JSONObject 键和 ArrayAgg 索引)进行排序。
输出 CharField、EmailField、SlugField、URLField、TextField 或 ArrayField 的 F() 和 OuterRef() 表达式现在可以 切片。
Model.refresh_from_db() 和 Model.arefresh_from_db() 的新 from_queryset 参数允许自定义用于重新加载模型值的查询集。这可以用于在重新加载之前锁定行或选择相关对象。
新的 Expression.constraint_validation_compatible 属性允许指定在约束验证期间忽略该表达式。
自定义标签现在可以在 Parser 对象上设置额外的数据,这些数据稍后将在 Template 实例上可用。例如,模板加载器或其他模板客户端可以使用这些数据。
模板引擎 现在实现了一个 check() 方法,该方法已经注册到检查框架中。
assertContains()、assertNotContains() 和 assertInHTML() 断言现在将干草堆添加到断言错误消息中。
RequestFactory、AsyncRequestFactory、Client 和 AsyncClient 类现在支持 query_params 参数,该参数接受查询字符串键和值的字典。这使得在任何 HTTP 方法上设置查询字符串变得更加容易。
self.client.post("/items/1", query_params={"action": "delete"})
await self.async_client.post("/items/1", query_params={"action": "delete"})
新的 SimpleTestCase.assertNotInHTML() 断言允许测试给定的 HTML 干草堆中不包含某个 HTML 片段。
为了强制测试隔离,SimpleTestCase 中不再允许在线程内使用数据库连接。
新的 DomainNameValidator 验证域名,包括国际化域名。新的 validate_domain_name() 函数返回 DomainNameValidator 的实例。
django.contrib.gis¶移除对 PostGIS 2.5 的支持。
已移除对 PROJ 版本低于 6 的支持。
移除对 GDAL 2.4 的支持。
GeoIP2 在提供目录路径时不再同时打开城市和国家数据库,而是优先使用城市数据库(如果可用)。国家数据库是城市数据库的子集,通常不需要同时使用两者。如果你需要在与城市数据库相同的目录中使用国家数据库,请显式地将国家数据库路径传递给构造函数。
上游对 MariaDB 10.4 的支持将于 2024 年 6 月结束。Django 5.1 支持 MariaDB 10.5 及更高版本。
上游对 PostgreSQL 12 的支持将于 2024 年 11 月结束。Django 5.1 支持 PostgreSQL 13 及更高版本。
为了提高可访问性,管理界面的变更列表过滤器现在在 <nav> 标签中渲染,而不是 <div>。
为了提高可访问性,管理界面的页脚现在在 <footer> 标签中渲染,而不是 <div>,并且移动到 <div id="main"> 元素下方。
为了提高可访问性,当字段集有名称并使用 collapse 类时,用于 ModelAdmin.fieldsets 和 InlineModelAdmin.fieldsets 的可展开小部件现在包含 <details> 和 <summary> 元素。
JavaScript 文件 collapse.js 已被移除,因为它在 Django 管理站点中不再需要。
SimpleTestCase.assertURLEqual() 和 assertInHTML() 现在在 msg_prefix 中添加 ": "。这与其他断言的行为一致。
truncatechars_html 和 truncatewords_html 模板过滤器使用的 django.utils.text.Truncator 现在使用 html.parser.HTMLParser 子类。这使得操作更加健壮和快速,但输出可能会有细微差异。
未记录的 django.urls.converters.get_converter() 函数已被移除。
SQLite 的最低支持版本从 3.27.0 提高到 3.31.0。
FileField 现在在保存没有 name 的文件时会引发 FieldError。
ImageField.update_dimension_fields(force=True) 在将图像保存到存储后不再调用。如果你的存储后端调整了图像大小,width_field 和 height_field 将与图像的宽度和高度不匹配。
asgiref 的最低支持版本从 3.7.0 提高到 3.8.1。
To improve performance, the delete_selected admin action now uses
QuerySet.bulk_create() when creating multiple LogEntry objects. As a
result, pre_save and post_save signals for LogEntry are not sent
when multiple objects are deleted via this admin action.
ModelAdmin.log_deletion() 和 LogEntryManager.log_action() 方法已被弃用。子类应实现 ModelAdmin.log_deletions() 和 LogEntryManager.log_actions()。
未记录的 django.utils.itercompat.is_iterable() 函数和 django.utils.itercompat 模块已被弃用。请使用 isinstance(..., collections.abc.Iterable) 代替。
django.contrib.gis.geoip2.GeoIP2.coords() 方法已被弃用。请使用 django.contrib.gis.geoip2.GeoIP2.lon_lat() 代替。
django.contrib.gis.geoip2.GeoIP2.open() 方法已被弃用。请使用 GeoIP2 构造函数代替。
在 Model.save() 和 Model.asave() 中传递位置参数已被弃用,建议仅使用关键字参数。
设置 django.contrib.gis.gdal.OGRGeometry.coord_dim 已被弃用。请使用 set_3d() 代替。
不推荐使用 django.urls.register_converter() 覆盖现有的转换器。
CheckConstraint 的 check 关键字参数已被弃用,建议使用 condition。
未记录的 FileSystemStorage 的 OS_OPEN_FLAGS 属性已被弃用。要允许覆盖存储中的文件,请将新的 allow_overwrite 选项设置为 True。
FieldCacheMixin 的 get_cache_name() 方法已被弃用,建议使用 cache_name 缓存属性。
这些功能已达到其弃用周期的末尾,并在 Django 5.1 中被移除。
有关这些更改的详细信息,包括如何移除这些功能的使用,请参阅 在 4.2 版本中弃用的功能。
BaseUserManager.make_random_password() 方法已被移除。
模型的 Meta.index_together 选项已被移除。
length_is 模板过滤器已被移除。
django.contrib.auth.hashers.SHA1PasswordHasher、django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher 和 django.contrib.auth.hashers.UnsaltedMD5PasswordHasher 已被移除。
django.contrib.postgres.fields.CICharField、django.contrib.postgres.fields.CIEmailField 和 django.contrib.postgres.fields.CITextField 模型已被移除,仅支持历史迁移。
django.contrib.postgres.fields.CIText 混入类已被移除。
BaseGeometryWidget 的 map_width 和 map_height 属性已被移除。
SimpleTestCase.assertFormsetError() 方法已被移除。
TransactionTestCase.assertQuerysetEqual() 方法已被移除。
支持将编码的 JSON 字符串字面量传递给 JSONField 及相关查找和表达式的功能已被移除。
支持将位置参数传递给 Signer 和 TimestampSigner 的功能已被移除。
DEFAULT_FILE_STORAGE 和 STATICFILES_STORAGE 设置已被移除。
django.core.files.storage.get_storage_class() 函数已被移除。
8月 13, 2025