August 3, 2022
欢迎来到Django 4.1!
这些发行说明涵盖 new features ,以及一些 backwards incompatible changes 在从Django 4.0或更早版本升级时,您需要注意这一点。我们已经 begun the deprecation process for some features 。
见 如何将Django升级到更新版本 如果正在更新现有项目,则提供指南。
Django 4.1支持Python3.8、3.9、3.10和3.11(从4.1.3开始)。我们 highly recommend 并且仅官方支持每个系列的最新版本。
视图子类现在可以定义异步HTTP方法处理程序::
import asyncio
from django.http import HttpResponse
from django.views import View
class AsyncView(View):
async def get(self, request, *args, **kwargs):
# Perform view logic using await.
await asyncio.sleep(1)
return HttpResponse("Hello async world!")
看见 基于类的异步视图 了解更多详细信息。
QuerySet 现在为所有数据访问操作提供一个异步接口。这些名称按现有的同步操作命名,但带有 a 前缀,例如 acreate() , aget() 以此类推。
新接口允许您编写异步代码,而无需将ORM操作包装在 sync_to_async() **
async for author in Author.objects.filter(name__startswith="A"):
book = await author.books.afirst()
请注意,在此阶段,底层数据库操作保持同步,正在进行将异步支持下推到SQL编译器中并集成异步数据库驱动程序的工作。新的异步查询集接口当前封装了必要的 sync_to_async() 操作,并将允许您的代码在ORM的异步支持发展过程中利用它的发展。
看见 异步查询 以了解详细信息和限制。
Check , unique ,以及 exclusion 中定义的约束 Meta.constraints 选项现在处于选中状态 model validation 。
为了帮助用户使用屏幕阅读器和其他辅助技术,新的 <div> 本版本提供基于表单模板的功能。与较旧的模板相比,这些模板提供了更易访问的导航,并且能够正确地将相关控件(如无线电列表)分组为字段集。
建议使用新模板,并将在输出表单时成为默认的表单呈现样式,如 {{ form }} 在模板中,来自Django 5.0。
为了便于采用新的输出样式,默认表单和表单集模板现在可以通过 FORM_RENDERER 布景。
看见 the Forms section (below) 获取完整的详细信息。
django.contrib.admin¶管理员 dark mode CSS variables 现在在单独的样式表和模板块中应用。
ModelAdmin 列表过滤器 提供定制 FieldListFilter 子类现在可以在筛选多个值时控制查询字符串值分隔符 __in 查一查。
管理员 history view 现在已分页。
相关的小部件包装现在有一个指向Object的更改表单的链接。
这个 AdminSite.get_app_list() 方法现在允许更改管理索引页面上应用程序和模型的顺序。
django.contrib.auth¶PBKDF2密码散列器的默认迭代计数从320,000增加到39,000。
这个 RemoteUserBackend.configure_user() 方法现在允许将用户属性与远程系统(如LDAP目录)中的属性同步。
django.contrib.gis¶新的 GEOSGeometry.make_valid() 方法允许将无效的几何图形转换为有效的几何图形。
新的 clone 论据 GEOSGeometry.normalize() 允许创建几何体的规格化克隆。
django.contrib.postgres¶新的 BitXor() 聚合函数返回一个 int 按位计算的 XOR 所有非空输入值的。
SpGistIndex 现在支持在PostgreSQL 14+上覆盖索引。
ExclusionConstraint 现在支持在PostgreSQL 14+上使用SP-GIST索引覆盖排除约束。
新的 default_bounds 的属性 DateTimeRangeField 和 DecimalRangeField 允许指定列表和元组输入的边界。
ExclusionConstraint 现在允许使用 OpClass() 表情。
django.contrib.sitemaps¶默认站点地图索引模板 <sitemapindex> 现在包括 <lastmod> 时间戳(如果可用),通过新的 get_latest_lastmod() 方法。自定义网站地图索引模板应针对调整后的 context variables 。
django.contrib.staticfiles¶ManifestStaticFilesStorage 现在用其哈希对应项替换指向CSS源映射引用的路径。
第三方数据库后端现在可以使用 DatabaseFeatures.minimum_database_version 属性,该属性是元组(例如 (10, 0) 意思是“10.0”)。如果指定了最低版本,后端也必须实现 DatabaseWrapper.get_database_version() ,它返回当前数据库版本的元组。后端的 DatabaseWrapper.init_connection_state() 方法必须调用 super() 才能运行检查。
转换为字符串时用于呈现表单的默认模板,例如在模板中为 {{ form }} 现在可以通过设置在项目级别进行配置 form_template_name 关于所提供的课程 FORM_RENDERER 。
Form.template_name 现在是服从呈现器的属性,但可以用字符串值覆盖,以指定每个表单类的模板名称。
同样,可以通过匹配指定用于呈现表单集的默认模板 formset_template_name 渲染器属性。
新的 div.html 表单模板,引用 Form.template_name_div 属性和匹配 Form.as_div() 方法,使用HTML语言呈现表单 <div> 元素。
建议使用这种新的输出样式,而不是现有的 as_table() , as_p() 和 as_ul() 样式,作为模板实现 <fieldset> 和 <legend> 对相关输入进行分组,屏幕阅读器用户可以更轻松地导航。
从Django 5.0开始,基于div的输出将成为默认的呈现样式。
为了顺利采用新的 <div> 输出样式,有两个过渡形式呈现器类可用: django.forms.renderers.DjangoDivFormRenderer 和 django.forms.renderers.Jinja2DivFormRenderer ,分别用于Django和JJIA2模板后端。
您可以通过 FORM_RENDERER 布景。例如::
FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
一旦 <div> 输出样式是默认的,从Django 5.0开始,这些过渡渲染器将被弃用,在Django 6.0中删除。这个 FORM_RENDERER 声明可以在那时被删除。
如果新的 <div> 输出样式不适合您的项目,您应该定义一个渲染器子类,指定 form_template_name 和 formset_template_name 为您所需的样式,并设置 FORM_RENDERER 相应地。
例如,对于 <p> 使用的输出样式 as_p() ,您将定义一个表单呈现器设置 form_template_name 至 "django/forms/p.html" 和 formset_template_name 至 "django/forms/formsets/p.html" 。
新的 legend_tag() 允许在中呈现字段标签 <legend> 通过新的 tag 的论点 label_tag() 。
新的 edit_only 论据 modelformset_factory() 和 inlineformset_factory() 允许阻止创建新对象。
这个 js 和 css 的类属性 Media 现在允许使用Hasable对象,而不仅仅是路径字符串,只要这些对象实现 __html__() 方法(通常在使用 html_safe() 装饰师)。
新的 BoundField.use_fieldset 和 Widget.use_fieldset 属性有助于标识小部件的输入应分组到 <fieldset> 使用一个 <legend> 。
这个 error_messages 论据 BaseFormSet 现在允许通过传递以下方法为无效数量的表单自定义错误消息 'too_few_forms' 和 'too_many_forms' 钥匙。
IntegerField , FloatField ,以及 DecimalField 现在可以选择接受一个 step_size 争论。它用于设置 step 属性,并在提交表单时进行验证。
这个 i18n_patterns() 函数现在支持具有脚本和区域的语言。
makemigrations --no-input 现在记录无法创建迁移的默认答案和原因。
新的 makemigrations --scriptable 选项将日志输出和输入提示转移到 stderr ,仅将生成的迁移文件的路径写入 stdout 。
新的 migrate --prune 选项允许删除不存在的迁移 django_migrations 桌子。
由创建者创建的Python文件 startproject , startapp , optimizemigration , makemigrations ,以及 squashmigrations 现在使用 black 命令(如果该命令存在于 PATH 。
新的 optimizemigration 命令允许优化迁移操作。
新的 RenameIndex 操作允许重命名在 Meta.indexes 或 index_together 选择。
迁移自动检测器现在生成 RenameIndex 操作而不是 RemoveIndex 和 AddIndex 中定义的索引重命名时 Meta.indexes 。
迁移自动检测器现在生成 RenameIndex 操作而不是 AlterIndexTogether 和 AddIndex 中定义的索引 Meta.index_together 发送到 Meta.indexes 。
这个 order_by 的论据 Window 表达式现在接受对字段和转换的字符串引用。
新的 CONN_HEALTH_CHECKS 设置允许启用运行状况检查 persistent database connections 以减少失败请求的数量,例如在数据库服务器重新启动之后。
QuerySet.bulk_create() 现在支持在行插入不符合唯一性约束时更新字段。这在MariaDB、MySQL、PostgreSQL和SQLite 3.24+上受支持。
QuerySet.iterator() 现在支持预取相关对象,只要 chunk_size 提供了参数。在较早的版本中,不执行预取。
Q 现在可以使用以下命令组合对象和查询集 ^ 作为独占OR (XOR )操作员。 XOR 在MariaDB和MySQL上受本地支持。对于不支持以下内容的数据库 XOR ,该查询将被转换为使用 AND , OR ,以及 NOT 。
新的 Field.non_db_attrs 属性允许定制不影响列定义的字段的属性。
在PostgreSQL上, AutoField , BigAutoField ,以及 SmallAutoField 现在创建为标识列,而不是具有序列的序列列。
HttpResponse.set_cookie() 现在支持 timedelta 对象的 max_age 争论。
新的 SECRET_KEY_FALLBACKS 设置允许提供密钥轮换的值列表。
这个 SECURE_PROXY_SSL_HEADER 设置现在支持标头值中以逗号分隔的协议列表。
这个 pre_delete 和 post_delete 信号现在发送给 origin 删除的内容。
超文本标记语言 <script> 元素 id 属性时不再需要 json_script 模板过滤器。
这个 cached template loader 现在在开发中启用,当 DEBUG 是 True ,以及 OPTIONS['loaders'] 未指定。您可以指定 OPTIONS['loaders'] 如有必要,可以推翻这一点。
这个 DiscoverRunner 现在支持在MacOS、Windows和任何其他默认系统上并行运行测试 multiprocessing 启动方法为 spawn 。
中标记为持久的嵌套原子块 django.test.TestCase 现在引发一个 RuntimeError ,与测试之外的情况相同。
SimpleTestCase.assertFormError() 和 assertFormsetError() 现在支持直接传递Form/FormSet对象。
新的 ResolverMatch.captured_kwargs 属性存储从URL解析的捕获的关键字参数。
新的 ResolverMatch.extra_kwargs 属性存储传递给view函数的其他关键字参数。
SimpleLazyObject 现在支持加法运算。
mark_safe() 现在保留惰性对象。
新的 StepValueValidator 检查值是否为给定步长的整数倍。此新验证器用于新的 step_size 添加到表示数值的表单字段中的参数。
本节描述第三方数据库后端可能需要的更改。
BaseDatabaseFeatures.has_case_insensitive_like 已从 True 至 False 以反映大多数数据库的行为。
DatabaseIntrospection.get_key_columns() 被移除。使用 DatabaseIntrospection.get_relations() 取而代之的是。
DatabaseOperations.ignore_conflicts_suffix_sql() 方法被替换为 DatabaseOperations.on_conflict_suffix_sql() 它接受 fields , on_conflict , update_fields ,以及 unique_fields 争论。
这个 ignore_conflicts 的论据 DatabaseOperations.insert_statement() 方法被替换为 on_conflict 那就接受 django.db.models.constants.OnConflict 。
DatabaseOperations._convert_field_to_tz() 被替换为 DatabaseOperations._convert_sql_to_tz() 它接受 sql , params ,以及 tzname 争论。
上的几种日期和时间方法 DatabaseOperations 现在拿着 sql 和 params 参数而不是 field_name 并返回包含一些SQL和要内插到该SQL中的参数的二元组。更改后的方法具有以下新签名:
DatabaseOperations.date_extract_sql(lookup_type, sql, params)
DatabaseOperations.datetime_extract_sql(lookup_type, sql, params, tzname)
DatabaseOperations.time_extract_sql(lookup_type, sql, params)
DatabaseOperations.date_trunc_sql(lookup_type, sql, params, tzname=None)
DatabaseOperations.datetime_trunc_sql(self, lookup_type, sql, params, tzname)
DatabaseOperations.time_trunc_sql(lookup_type, sql, params, tzname=None)
DatabaseOperations.datetime_cast_date_sql(sql, params, tzname)
DatabaseOperations.datetime_cast_time_sql(sql, params, tzname)
django.contrib.gis¶删除了对GDAL 2.1的支持。
删除了对PostGIS 2.4的支持。
对PostgreSQL 10的上游支持将于2022年11月结束。Django 4.1支持PostgreSQL 11及更高版本。
对MariaDB 10.2的上游支持将于2022年5月结束。Django 4.1支持MariaDB 10.3及更高版本。
使用多个搜索词的管理员更改列表搜索现在可以在单个呼叫中应用到 filter() ,而不是按顺序 filter() 打电话。
对于多值关系,这意味着相关模型中的行必须匹配所有术语,而不是任何术语。例如,如果 search_fields 设置为 ['child__name', 'child__age'] ,并且用户搜索 'Jamal 17' ,只有在与某个名为Jamal的17岁孩子有关系的情况下,才会返回父行,而不是返回除了其他17岁的孩子外,只有一个更小或更大的孩子叫Jamal的父母。
请参阅 跨越多值关系 主题,以了解有关这种差异的更多讨论。在Django 4.0及更早版本中, get_search_results() 遵循第二个示例查询,但这种未记录的行为会导致查询具有过多的联接。
为了将行为与未保存的模型实例的多对多关系统一起来,现在引发反向外键 ValueError 当呼叫时 related managers 用于未保存的对象。
的相关经理 ForeignKey , ManyToManyField ,以及 GenericRelation 现在缓存在 Model 它们所属的实例。 This change was reverted in Django 4.1.2.
DiscoverRunner 标记的测试的意外成功,现在返回非零错误代码。 unittest.expectedFailure() 。
CsrfViewMiddleware 不再像屏蔽DOM中的CSRF令牌那样屏蔽CSRF Cookie。
CsrfViewMiddleware 现在使用 request.META['CSRF_COOKIE'] 用于存储未屏蔽的CSRF秘密,而不是屏蔽的版本。这是一个未记录的私有API。
这个 ModelAdmin.actions 和 inlines 属性现在默认为空的元组,而不是空的列表,以防止意外的突变。
这个 type="text/css" 属性不再包含在 <link> 用于CSS的标签 form media 。
formset:added 和 formset:removed 现在,JavaScript事件是纯JavaScript事件,不依赖于jQuery。看见 内联窗体事件 有关更改的更多详细信息,请访问。
这个 exc_info 无证之辩 django.utils.log.log_response() 函数被替换为 exception 。
这个 size 无证之辩 django.views.static.was_modified_since() 函数被删除。
管理员注销用户界面现在使用 POST 请求。
未登记的人 InlineAdminFormSet.non_form_errors 属性被替换为 non_form_errors() 方法。这与以下情况一致 BaseFormSet 。
按规定 above ,缓存模板加载器现已在开发中启用。您可以指定 OPTIONS['loaders'] 如有必要,可以推翻这一点。
未登记的人 django.contrib.auth.views.SuccessURLAllowedHostsMixin Mixin被替换为 RedirectURLMixin 。
BaseConstraint 子类必须实现 validate() 方法,以允许使用这些约束进行验证。
未登记的人 URLResolver._is_callback() , URLResolver._callback_strs ,以及 URLPattern.lookup_str() 已移至 django.contrib.admindocs.utils 。
这个 Model.full_clean() 方法现在将一个 exclude 值设置为 set 。更可取的是,通过一个 exclude 价值作为 set 发送到 Model.clean_fields() , Model.full_clean() , Model.validate_unique() ,以及 Model.validate_constraints() 方法:研究方法。
支持的最低版本 asgiref 从3.4.1增加到3.5.2。
组合表达式不再使用容易出错的猜测行为 output_field 当参数类型匹配时。因此,解决 output_field 对于数据库函数和组合表达式,混合类型现在可能会崩溃。您将需要显式设置 output_field 在这种情况下。
这个 makemessages 命令不再更改 .po 最新的文件。在较旧的版本中, POT-Creation-Date 总是更新的。
通过以下方式注销 GET 向 built-in logout view 已弃用。使用 POST 而不是请求。
如果要保留HTML链接的用户体验,可以使用样式设置为链接的表单:
<form id="logout-form" method="post" action="{% url 'admin:logout' %}">
{% csrf_token %}
<button type="submit">{% translate "Log out" %}</button>
</form>
#logout-form {
display: inline;
}
#logout-form button {
background: none;
border: none;
cursor: pointer;
padding: 0;
text-decoration: underline;
}
不推荐使用URL平面列表的站点地图索引模板的上下文。自定义网站地图索引模板应针对调整后的 context variables ,需要一个对象列表 location 和可选 lastmod 属性。
CSRF_COOKIE_MASKED 过渡设置已弃用。
这个 name 的论点 django.utils.functional.cached_property() 已弃用,因为从Python3.6开始这是不必要的。
这个 opclasses 的论点 django.contrib.postgres.constraints.ExclusionConstraint 不推荐使用,而支持使用 OpClass() 在……里面 ExclusionConstraint.expressions 。要使用它,您需要添加 'django.contrib.postgres' 在你的 INSTALLED_APPS 。
在做了这个改变之后, makemigrations 将生成包含两个操作的新迁移: RemoveConstraint 和 AddConstraint 。由于此更改对数据库架构没有影响,因此 SeparateDatabaseAndState 操作只能用于更新迁移状态,而不运行任何SQL。将生成的操作移动到 state_operations 的论点 SeparateDatabaseAndState 。例如::
class Migration(migrations.Migration):
...
operations = [
migrations.SeparateDatabaseAndState(
database_operations=[],
state_operations=[
migrations.RemoveConstraint(...),
migrations.AddConstraint(...),
],
),
]
未登记的传球能力 errors=None 至 SimpleTestCase.assertFormError() 和 assertFormsetError() 已弃用。使用 errors=[] 取而代之的是。
django.contrib.sessions.serializers.PickleSerializer 由于存在远程代码执行的风险,因此不推荐使用。
的用法 QuerySet.iterator() 在预取相关对象而不提供 chunk_size 参数已弃用。在较早的版本中,不执行预取。为提供值 chunk_size 表示需要预取所需的每个区块的额外查询。
不建议将未保存的模型实例传递给相关筛选器。在Django 5.0中,将引发例外。
created=True 添加到的签名中 RemoteUserBackend.configure_user() 。支持 RemoteUserBackend 不建议使用不接受此参数的子类。
这个 django.utils.timezone.utc 别名到 datetime.timezone.utc 已弃用。使用 datetime.timezone.utc 直接去吧。
将响应对象和表单/表单集名称传递给 SimpleTestCase.assertFormError() 和 assertFormsetError() 已弃用。使用::
assertFormError(response.context["form_name"], ...)
assertFormsetError(response.context["formset_name"], ...)
或者直接传递Form/FormSet对象。
未登记的人 django.contrib.gis.admin.OpenLayersWidget 已弃用。
django.contrib.auth.hashers.CryptPasswordHasher 已弃用。
传球的能力 nulls_first=False 或 nulls_last=False 至 Expression.asc() 和 Expression.desc() 方法,以及 OrderBy 表达式已弃用。使用 None 取而代之的是。
这个 "django/forms/default.html" 和 "django/forms/formsets/default.html" 不建议使用作为基于表的模板的代理的模板。请改用特定的模板。
未登记的人 LogoutView.get_next_page() 方法被重命名为 get_success_url() 。
这些功能已经到了弃用周期的末尾,并在Django 4.1中被删除。
看见 3.2中废弃的功能 有关这些更改的详细信息,包括如何删除这些功能的使用。
支持分配不支持使用创建深层副本的对象 copy.deepcopy() 要将中的属性分类,请执行以下操作 TestCase.setUpTestData() 被移除。
支持在中使用布尔值 BaseCommand.requires_system_checks 被移除。
这个 whitelist 论据和 domain_whitelist 的属性 django.core.validators.EmailValidator 都被移除了。
这个 default_app_config 删除应用程序配置变量。
TransactionTestCase.assertQuerysetEqual() 不再来电 repr() 在与字符串值进行比较时对查询集执行。
这个 django.core.cache.backends.memcached.MemcachedCache 后端被删除。
支持Django 3.2之前的消息格式,由 django.contrib.messages.storage.cookie.CookieStorage 被移除。
5月 28, 2025