Django 5.0 发行说明¶
2023 年 12 月 4 日
欢迎来到 Django 5.0!
这些发行说明涵盖了新功能,以及从 Django 4.2 或更早版本升级时需要注意的一些向后不兼容的更改。我们已经 开始对某些功能进行弃用流程。
如果您要更新现有项目,请参阅如何将 Django 升级到更新版本指南。
Python 兼容性¶
Django 5.0 支持 Python 3.10、3.11 和 3.12。我们强烈推荐并仅官方支持每个系列的最新版本。
Django 4.2.x 系列是最后一个支持 Python 3.8 和 3.9 的版本。
对旧版本 Django 的第三方库支持¶
Django 5.0 发布后,我们建议第三方应用程序作者放弃对 Django 4.2 之前的所有版本的支持。那时,您应该能够使用运行包的测试,以便出现弃用警告。修复弃用警告后,您的应用程序应该与 Django 5.0 兼容。python -Wd
Django 5.0 中的新增功能¶
管理中的方面过滤器¶
现在,当通过 UI 切换时,会在管理更改列表中显示已应用过滤器的构面计数。可以通过新属性更改此行为 ModelAdmin.show_facets。有关详细信息,请参阅 构面。
表单字段渲染的简化模板¶
Django 5.0 引入了字段组和字段组模板的概念。这简化了 Django 表单字段相关元素的呈现,例如标签、小部件、帮助文本和错误。
例如下面的模板:
python
<form>
...
<div>
{{ form.name.label_tag }}
{% if form.name.help_text %}
<div class="helptext" id="{{ form.name.auto_id }}_helptext">
{{ form.name.help_text|safe }}
</div>
{% endif %}
{{ form.name.errors }}
{{ form.name }}
<div class="row">
<div class="col">
{{ form.email.label_tag }}
{% if form.email.help_text %}
<div class="helptext" id="{{ form.email.auto_id }}_helptext">
{{ form.email.help_text|safe }}
</div>
{% endif %}
{{ form.email.errors }}
{{ form.email }}
</div>
<div class="col">
{{ form.password.label_tag }}
{% if form.password.help_text %}
<div class="helptext" id="{{ form.password.auto_id }}_helptext">
{{ form.password.help_text|safe }}
</div>
{% endif %}
{{ form.password.errors }}
{{ form.password }}
</div>
</div>
</div>
...
</form>
现在可以简化为:
python
<form>
...
<div>
{{ form.name.as_field_group }}
<div class="row">
<div class="col">{{ form.email.as_field_group }}</div>
<div class="col">{{ form.password.as_field_group }}</div>
</div>
</div>
...
</form>
as_field_group()默认情况下使用模板呈现字段 "django/forms/field.html"
,并且可以根据每个项目、每个字段或每个请求进行自定义。请参阅 可重复使用的字段组模板。
数据库生成的模型字段¶
新功能GeneratedField允许创建数据库生成的列。该字段可在所有支持的数据库后端上使用,以创建始终根据其他字段计算的字段。例如:
python
from django.db import models
from django.db.models import F
class Square(models.Model):
side = models.IntegerField()
area = models.GeneratedField(
expression=F("side") * F("side"),
output_field=models.BigIntegerField(),
db_persist=True,
)
用于声明字段选择的更多选项¶
Field.choices (对于模型字段) 和*(对于表单字段)* 在声明其值时允许更大的灵活性。在 Django 的早期版本中,应该是二元组列表,或者是枚举类型子类,但后者需要访问属性以提供预期形式的值:ChoiceField.choices choices``.choices
python
from django.db import models
Medal = models.TextChoices("Medal", "GOLD SILVER BRONZE")
SPORT_CHOICES = [
("Martial Arts", [("judo", "Judo"), ("karate", "Karate")]),
("Racket", [("badminton", "Badminton"), ("tennis", "Tennis")]),
("unknown", "Unknown"),
]
class Winner(models.Model):
name = models.CharField(...)
medal = models.CharField(..., choices=Medal.choices)
sport = models.CharField(..., choices=SPORT_CHOICES)
Django 5.0 添加了对接受映射或可调用而不是可迭代的支持,并且不再需要.choices
直接用于扩展枚举类型:
python
from django.db import models
Medal = models.TextChoices("Medal", "GOLD SILVER BRONZE")
SPORT_CHOICES = { # Using a mapping instead of a list of 2-tuples.
"Martial Arts": {"judo": "Judo", "karate": "Karate"},
"Racket": {"badminton": "Badminton", "tennis": "Tennis"},
"unknown": "Unknown",
}
def get_scores():
return [(i, str(i)) for i in range(10)]
class Winner(models.Model):
name = models.CharField(...)
medal = models.CharField(..., choices=Medal) # Using `.choices` not required.
sport = models.CharField(..., choices=SPORT_CHOICES)
score = models.IntegerField(choices=get_scores) # A callable is allowed.
在幕后,每当更新值时,所提供的choices
都会被标准化为 2 元组列表作为规范形式。choices
有关更多信息,请检查选项上的模型字段参考。
小功能¶
django.contrib.admin¶
- 新AdminSite.get_log_entries()方法允许自定义站点列出的日志条目的查询集。
django.contrib.admin.AllValuesFieldListFilter
、ChoicesFieldListFilter
、RelatedFieldListFilter
和 admin过滤RelatedOnlyFieldListFilter
器现在可以处理多值查询参数。XRegExp
从版本3.2.0升级到5.1.1。- 新AdminSite.get_model_admin()方法返回给定模型类的管理类。
- 属性ModelAdmin.list_display现在支持
boolean
属性。 - jQuery从版本3.6.4升级到3.7.1。
django.contrib.auth¶
- PBKDF2 密码哈希器的默认迭代计数从 600,000 增加到 720,000。
- 现在提供新的异步函数,使用
a
前缀:django.contrib.auth.aauthenticate()、 aget_user()、 alogin()、alogout()和aupdate_session_auth_hash()。 AuthenticationMiddleware
现在添加了一个HttpRequest.auser() 返回当前登录用户的异步方法。- 新的django.contrib.auth.hashers.acheck_password()异步函数和AbstractBaseUser.acheck_password()方法允许异步检查用户密码。
django.contrib.contenttypes¶
- QuerySet.prefetch_related()现在支持 GenericForeignKey使用非同质结果集进行预取。
django.contrib.gis¶
- 新 ClosestPoint() 函数返回几何体上最接近另一个几何体的二维点。
- GIS 聚合现在支持这一
filter
论点。 - 添加了对 GDAL 3.7 和 GEOS 3.12 的支持。
- 新GEOSGeometry.equals_identical()方法允许对几何进行逐点等价检查。
django.contrib.messages¶
- 新的MessagesTestMixin.assertMessages()断言方法允许将测试messages添加到 response.
django.contrib.postgres¶
- 新violation_error_code属性 ExclusionConstraint允许自定义模型验证期间引发
code
的。ValidationError
异步视图¶
- 现在在 ASGI 下
http.disconnect
处理事件。如果客户端在生成响应之前断开连接,这允许视图执行任何必要的清理。有关更多详细信息,请参阅处理断开连接。
装饰器¶
- 以下装饰器现在支持包装异步视图函数:
- cache_control()
- never_cache()
- no_append_slash()
- csrf_exempt()
- csrf_protect()
- ensure_csrf_cookie()
- requires_csrf_token()
- sensitive_variables()
- sensitive_post_parameters()
- gzip_page()
- condition()
conditional_page()
- etag()
- last_modified()
- require_http_methods()
- require_GET()
- require_POST()
- require_safe()
- vary_on_cookie()
- vary_on_headers()
xframe_options_deny()
xframe_options_sameorigin()
xframe_options_exempt()
错误报告¶
- sensitive_variables()现在可以 sensitive_post_parameters()与异步函数一起使用。
文件存储¶
- File.open()现在将所有位置 (
*args
) 和关键字参数 (**kwargs
) 传递给 Python 的内置open().
形式¶
- 新assume_scheme参数 URLField允许指定默认 URL 方案。
- 为了提高可访问性,进行了以下更改:
- 表单字段现在包含
aria-describedby
HTML 属性,使屏幕阅读器能够将表单字段与其帮助文本相关联。
- 表单字段现在包含
- 无效的表单字段现在包含
aria-invalid="true"
HTML 属性。
国际化¶
- 现已提供维吾尔语的支持和翻译。
迁移¶
- functools.cache()现在支持用或 装饰的函数的序列化,functools.lru_cache()而无需编写自定义序列化程序。
楷模¶
- 和方法
create_defaults
的新参数允许为创建操作指定不同的字段值。QuerySet.update_or_create()QuerySet.aupdate_or_create() - 新
violation_error_code
属性 BaseConstraint, CheckConstraint, 和 UniqueConstraint允许自定义模型验证期间引发code
的。ValidationError
- 现在的 force_insert参数Model.save()允许指定必须强制插入的父类的元组。
- QuerySet.bulk_create() 现在,当启用参数时(如果数据库支持),方法QuerySet.abulk_create()会在每个模型实例上设置主键。
update_conflicts
- 新UniqueConstraint.nulls_distinct属性允许在 PostgreSQL 15+ 上自定义值的处理
NULL
。 - 新的aget_object_or_404()异步 aget_list_or_404()快捷方式允许异步获取对象。
- 新aprefetch_related_objects()函数允许异步预取模型实例。
- QuerySet.aiterator()现在支持以前的调用
prefetch_related()
。 - 在 MariaDB 10.7+ 上,
UUIDField
现在创建为UUID
列而不是CHAR(32)
列。有关在 MariaDB 10.7+ 上迁移现有 UUIDField 的更多详细信息,请参阅上面的迁移指南 。 - Django 现在支持oracledb版本 1.3.2 或更高版本。
cx_Oracle
自此版本起,对 的支持 已弃用,并将在 Django 6.0 中删除。
分页¶
- 新django.core.paginator.Paginator.error_messages参数允许自定义 引发的错误消息Paginator.page()。
信号¶
- 新的Signal.asend()和Signal.asend_robust()方法允许异步信号调度。信号接收器可以是同步的或异步的,并且将自动适应正确的调用方式。
模板¶
测试¶
- Client现在AsyncClient提供异步方法,使用
a
前缀: asession()、alogin()、 aforce_login()和 alogout()。 - AsyncClient现在支持该
follow
参数。 - 新选项允许显示 Python 3.12+ 上最慢测试的持续时间。test --durations
验证器¶
- 新
offset
参数 StepValueValidator允许指定有效值的偏移量。
5.0 中向后不兼容的更改¶
数据库后端API ¶
本节描述第三方数据库后端可能需要的更改。
DatabaseFeatures.supports_expression_defaults``False
如果数据库不支持使用数据库函数作为默认值,则应设置为。DatabaseFeatures.supports_default_keyword_in_insert``False
如果数据库不支持查询DEFAULT
中的关键字 ,则应设置为INSERT
。DatabaseFeatures.supports_default_keyword_in_bulk_insert``False
如果数据库不支持DEFAULT
批量查询中的关键字 ,则应设置为INSERT
。
django.contrib.gis¶
- 删除了对 GDAL 2.2 和 2.3 的支持。
- 删除了对 GEOS 3.6 和 3.7 的支持。
django.contrib.sitemaps¶
- 由于 Google Sitemaps ping 端点已弃用,该
django.contrib.sitemaps.ping_google()
功能和ping_google
管理命令已被删除,并将于 2024 年 1 月删除。 - 异常
django.contrib.sitemaps.SitemapNotFound
类被删除。
放弃对 MySQL < 8.0.11 的支持¶
删除了对 MySQL 8.0.x 系列预发行版的支持。Django 5.0 支持 MySQL 8.0.11 及更高版本。
create_defaults__exact
现在可能需要使用QuerySet.update_or_create()
¶
QuerySet.update_or_create()现在支持参数 create_defaults
. 因此,任何具有 create_defaults
与 一起使用的名为 的字段的模型update_or_create()
都应该在查找中使用 指定该字段create_defaults__exact
。
迁移UUIDField
MariaDB 10.7+ 上的现有版本¶
在 MariaDB 10.7+ 上,UUIDField
现在创建为UUID
列而不是 CHAR(32)
列。因此,UUIDField
在 Django < 5.0 中创建的任何内容都应该替换为以下UUIDField
子类 CHAR(32)
:
class Char32UUIDField(models.UUIDField):
def db_type(self, connection):
return "char(32)"
例如:
class MyModel(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
应该变成:
class Char32UUIDField(models.UUIDField):
def db_type(self, connection):
return "char(32)"
class MyModel(models.Model):
uuid = Char32UUIDField(primary_key=True, default=uuid.uuid4)
运行该makemigrations命令将生成包含无操作操作的迁移AlterField
。
各种各样的¶
instance
未记录方法的参数 被BaseModelFormSet.save_existing()
重命名为obj
。- 无证的
django.contrib.admin.helpers.checkbox
被删除。 - 整数字段现在在 SQLite 上验证为 64 位整数,以匹配
sqlite3
. - 未记录的
Query.annotation_select_mask
属性从一组字符串更改为有序的字符串列表。 ImageField.update_dimension_fields()``post_init
如果width_field
和height_field
未设置,则不再在信号上调用 。- Now现在使用数据库功能
LOCALTIMESTAMP
而不是CURRENT_TIMESTAMP
Oracle 上的功能。 - AdminSite.site_header现在在标签中呈现,
<div>
而不是在<h1>
. 屏幕阅读器用户依靠标题元素在页面内进行导航。有两个<h1>
元素很令人困惑,而且站点标题没有帮助,因为它在所有页面上重复。 - 为了提高可访问性,管理员的主要内容区域和标题内容区域现在呈现在 a
<main>
和<header>
标记中,而不是<div>
。 - 在不支持 SQL
XOR
运算符的数据库上,^
异或 (XOR
) 运算符现在返回与奇数个操作数匹配的行,而不是仅与一个操作数匹配。这与 MySQL、MariaDB 和 Python 的行为一致。 - 最低支持版本
asgiref
从 3.6.0 增加到 3.7.0。 - 最低支持版本
selenium
从 3.8.0 增加到 4.8.0。 - 和例外
AlreadyRegistered
情况NotRegistered
从django.contrib.admin.sites
移至django.contrib.admin.exceptions
。 - SQLite 的最低支持版本从 3.21.0 增加到 3.27.0。
cx_Oracle
删除了对 <8.3 的支持。- 现在,在应用程序注册表完全填充之前执行 SQL 查询会引发RuntimeWarning.
- BadRequest针对具有application/x-www-form-urlencoded 内容类型的非 UTF-8 编码请求引发。看RFC 1866了解更多详细信息。
- 最低支持版本
colorama
增加至0.4.6。 - 最低支持版本
docutils
增加至0.19。
5.0 中弃用的功能¶
各种各样的¶
- 和过渡形式
DjangoDivFormRenderer
渲染Jinja2DivFormRenderer
器已被弃用。 - 不推荐使用传递位置参数
name
和violation_error_message
to BaseConstraint,而是使用仅关键字参数。 request
添加到 的签名中ModelAdmin.lookup_allowed()。不推荐支持ModelAdmin
不接受此参数的子类。- and 方法
get_joining_columns()
已被弃用。从 Django 6.0 开始, 将不再回退到 . 子类应该 代替实现。ForeignObject``ForeignObjectRel``django.db.models.sql.datastructures.Join``get_joining_columns()``get_joining_fields()
- 该
ForeignObject.get_reverse_joining_columns()
方法已被弃用。 - 在 Django 6.0 中,默认方案
forms.URLField
将从 更改"http"
为"https"
。将FORMS_URLFIELD_ASSUME_HTTPS 过渡设置设置为True
选择"https"
在 Django 5.x 发布周期期间进行假设。 FORMS_URLFIELD_ASSUME_HTTPS
过渡设置已被弃用。- 对不传递 args 或 kwargs 的调用的支持
format_html()
将被删除。 cx_Oracle
不推荐使用对oracledb 1.3.2+ Python 驱动程序的支持。DatabaseOperations.field_cast_sql()
已被弃用,取而代之的是DatabaseOperations.lookup_cast()
. 从 Django 6.0 开始,BuiltinLookup.process_lhs()
将不再调用field_cast_sql()
. 第三方数据库后端应该改为实施lookup_cast()
。- 元
django.db.models.enums.ChoicesMeta
类被重命名为ChoicesType
. - 该
Prefetch.get_current_queryset()
方法已被弃用。 - 相关管理器和描述符的方法
get_prefetch_queryset()
已被弃用。从 Django 6.0 开始,get_prefetcher()
将prefetch_related_objects()
不再回退到get_prefetch_queryset()
. 子类应该get_prefetch_querysets()
代替实现。
5.0 中删除的功能¶
这些功能已达到其弃用周期的末尾,并在 Django 5.0 中删除。
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅4.0 中已弃用的功能。
- 测试
SERIALIZE
设置已删除。 - 未记录的
django.utils.baseconv
模块已被删除。 - 未记录的
django.utils.datetime_safe
模块已被删除。 - 设置的默认值
USE_TZ
从 更改False
为True
。 - 在请求上下文之外构建的站点地图的默认站点地图协议已从 更改
'http'
为'https'
。 - 和
extra_tests
的参数被删除。DiscoverRunner.build_suite()``DiscoverRunner.run_tests()
- 当没有行时
django.contrib.postgres.aggregates.ArrayAgg
,JSONBAgg
、 和 聚合StringAgg
不再分别返回[]
、[]
和。''
- 该
USE_L10N
设置被删除。 - 过渡
USE_DEPRECATED_PYTZ
设置被删除。 pytz
删除了对时区的支持。- 该
is_dst
参数被删除:QuerySet.datetimes()
django.utils.timezone.make_aware()
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.contrib.gis.admin.GeoModelAdmin
类OSMGeoAdmin
被删除。 - 未记录的
BaseForm._html_output()
方法已被删除。 - 渲染and时返回 a
str
而非 a 的功能已被删除。SafeString``ErrorDict``ErrorList
有关这些更改的详细信息,包括如何删除这些功能的使用,请参阅4.1 中已弃用的功能。
- 该
SitemapIndexItem.__str__()
方法已被删除。 - 过渡
CSRF_COOKIE_MASKED
设置被删除。 name
的参数被django.utils.functional.cached_property()
删除。opclasses
的参数 被django.contrib.postgres.constraints.ExclusionConstraint
删除。errors=None
未记录的传递给SimpleTestCase.assertFormError()
和 的能力assertFormsetError()
被删除。django.contrib.sessions.serializers.PickleSerializer
已移除。- 不再允许在不提供参数的情况下使用
QuerySet.iterator()
预取相关对象的查询集。chunk_size
- 不再允许将未保存的模型实例传递给相关过滤器。
created=True
子类的签名中需要RemoteUserBackend.configure_user()
。- 通过和
GET
中的请求 注销的支持已被删除。django.contrib.auth.views.LogoutView``django.contrib.auth.views.logout_then_login()
- 别名
django.utils.timezone.utc
todatetime.timezone.utc
已删除。 - 不再允许将响应对象和表单/表单集名称传递给
SimpleTestCase.assertFormError()
and 。assertFormSetError()
- 已
django.contrib.gis.admin.OpenLayersWidget
删除。
- 已
django.contrib.auth.hashers.CryptPasswordHasher
删除。
- 和
"django/forms/default.html"
模板"django/forms/formsets/default.html"
被删除。 - 默认表单和表单集渲染样式更改为基于 div。
- 将
nulls_first=False
ornulls_last=False
传递给Expression.asc()
andExpression.desc()
方法,并且OrderBy
不再允许使用表达式。