Django5.0发布

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.AllValuesFieldListFilterChoicesFieldListFilterRelatedFieldListFilter和 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
django.contrib.contenttypes
django.contrib.gis
django.contrib.messages
django.contrib.postgres
异步视图
  • 现在在 ASGI 下http.disconnect处理事件。如果客户端在生成响应之前断开连接,这允许视图执行任何必要的清理。有关更多详细信息,请参阅处理断开连接。
装饰器
错误报告
文件存储
  • File.open()现在将所有位置 ( *args) 和关键字参数 ( **kwargs) 传递给 Python 的内置open().
形式
  • assume_scheme参数 URLField允许指定默认 URL 方案。
  • 为了提高可访问性,进行了以下更改:
    • 表单字段现在包含aria-describedbyHTML 属性,使屏幕阅读器能够将表单字段与其帮助文本相关联。
  • 无效的表单字段现在包含aria-invalid="true"HTML 属性。
国际化
  • 现已提供维吾尔语的支持和翻译。
迁移
楷模
分页
信号
模板
测试
验证器

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

迁移UUIDFieldMariaDB 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_fieldheight_field未设置,则不再在信号上调用 。
  • Now现在使用数据库功能 LOCALTIMESTAMP而不是CURRENT_TIMESTAMPOracle 上的功能。
  • AdminSite.site_header现在在标签中呈现,<div>而不是在 <h1>. 屏幕阅读器用户依靠标题元素在页面内进行导航。有两个<h1>元素很令人困惑,而且站点标题没有帮助,因为它在所有页面上重复。
  • 为了提高可访问性,管理员的主要内容区域和标题内容区域现在呈现在 a<main><header>标记中,而不是 <div>
  • 在不支持 SQLXOR运算符的数据库上,^异或 ( XOR) 运算符现在返回与奇数个操作数匹配的行,而不是仅与一个操作数匹配。这与 MySQL、MariaDB 和 Python 的行为一致。
  • 最低支持版本asgiref从 3.6.0 增加到 3.7.0。
  • 最低支持版本selenium从 3.8.0 增加到 4.8.0。
  • 和例外AlreadyRegistered情况NotRegistereddjango.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器已被弃用。
  • 不推荐使用传递位置参数nameviolation_error_messageto 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从 更改FalseTrue
  • 在请求上下文之外构建的站点地图的默认站点地图协议已从 更改'http''https'
  • extra_tests的参数被删除。DiscoverRunner.build_suite()``DiscoverRunner.run_tests()
  • 当没有行时django.contrib.postgres.aggregates.ArrayAggJSONBAgg、 和 聚合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.GeoModelAdminOSMGeoAdmin被删除。
  • 未记录的BaseForm._html_output()方法已被删除。
  • 渲染and时返回 astr而非 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.utctodatetime.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=Falseornulls_last=False传递给Expression.asc() andExpression.desc()方法,并且OrderBy不再允许使用表达式。
相关推荐
Open-AI14 分钟前
Python如何判断一个数是几位数
python
极客代码17 分钟前
【Python TensorFlow】入门到精通
开发语言·人工智能·python·深度学习·tensorflow
义小深20 分钟前
TensorFlow|咖啡豆识别
人工智能·python·tensorflow
疯一样的码农24 分钟前
Python 正则表达式(RegEx)
开发语言·python·正则表达式
进击的六角龙1 小时前
Python中处理Excel的基本概念(如工作簿、工作表等)
开发语言·python·excel
一只爱好编程的程序猿2 小时前
Java后台生成指定路径下创建指定名称的文件
java·python·数据下载
Aniay_ivy2 小时前
深入探索 Java 8 Stream 流:高效操作与应用场景
java·开发语言·python
gonghw4032 小时前
DearPyGui学习
python·gui
向阳12182 小时前
Bert快速入门
人工智能·python·自然语言处理·bert
engchina2 小时前
Neo4j 和 Python 初学者指南:如何使用可选关系匹配优化 Cypher 查询
数据库·python·neo4j