{"title":"Django 5.0 release notes","version":"dev","locale":"en","docname":"releases/5.0","url":"/en/dev/releases/5.0/","canonical":"https://djangodocs.dev/en/dev/releases/5.0/","summary":"Welcome to Django 5.0! These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading…","html":"<h1>Django 5.0 release notes<a class=\"heading-anchor\" href=\"#django-5-0-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><em>December 4, 2023</em></p>\n<p>Welcome to Django 5.0!</p>\n<p>These release notes cover the <a class=\"reference internal\" href=\"#whats-new-5-0\"><span class=\"std std-ref\">new features</span></a>, as well as\nsome <a class=\"reference internal\" href=\"#backwards-incompatible-5-0\"><span class=\"std std-ref\">backwards incompatible changes</span></a> you’ll\nwant to be aware of when upgrading from Django 4.2 or earlier. We’ve\n<a class=\"reference internal\" href=\"#deprecated-features-5-0\"><span class=\"std std-ref\">begun the deprecation process for some features</span></a>.</p>\n<p>See the <a class=\"reference internal\" href=\"/en/dev/howto/upgrade-version/\"><span class=\"doc\">How to upgrade Django to a newer version</span></a> guide if you’re updating an existing\nproject.</p>\n<section id=\"python-compatibility\">\n<h2>Python compatibility<a class=\"heading-anchor\" href=\"#python-compatibility\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 5.0 supports Python 3.10, 3.11, and 3.12. We <strong>highly recommend</strong> and\nonly officially support the latest release of each series.</p>\n<p>The Django 4.2.x series is the last to support Python 3.8 and 3.9.</p>\n</section>\n<section id=\"third-party-library-support-for-older-version-of-django\">\n<h2>Third-party library support for older version of Django<a class=\"heading-anchor\" href=\"#third-party-library-support-for-older-version-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Following the release of Django 5.0, we suggest that third-party app authors\ndrop support for all versions of Django prior to 4.2. At that time, you should\nbe able to run your package’s tests using <code class=\"docutils literal notranslate\">python -Wd</code> so that deprecation\nwarnings appear. After making the deprecation warning fixes, your app should be\ncompatible with Django 5.0.</p>\n</section>\n<section id=\"what-s-new-in-django-5-0\">\n<span id=\"whats-new-5-0\"></span><h2>What’s new in Django 5.0<a class=\"heading-anchor\" href=\"#what-s-new-in-django-5-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"facet-filters-in-the-admin\">\n<h3>Facet filters in the admin<a class=\"heading-anchor\" href=\"#facet-filters-in-the-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Facet counts are now shown for applied filters in the admin changelist when\ntoggled on via the UI. This behavior can be changed via the new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.show_facets\" title=\"django.contrib.admin.ModelAdmin.show_facets\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.show_facets</code></a> attribute. For more information see\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/filters/#facet-filters\"><span class=\"std std-ref\">Facets</span></a>.</p>\n</section>\n<section id=\"simplified-templates-for-form-field-rendering\">\n<h3>Simplified templates for form field rendering<a class=\"heading-anchor\" href=\"#simplified-templates-for-form-field-rendering\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 5.0 introduces the concept of a field group, and field group templates.\nThis simplifies rendering of the related elements of a Django form field such\nas its label, widget, help text, and errors.</p>\n<p>For example, the template below:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.name.label_tag</span> <span class=\"cp\">}}</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">form.name.help_text</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;helptext&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.name.auto_id</span> <span class=\"cp\">}}</span><span class=\"s\">_helptext&quot;</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.name.help_text</span><span class=\"o\">|</span><span class=\"nf\">safe</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.name.errors</span> <span class=\"cp\">}}</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.name</span> <span class=\"cp\">}}</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;row&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;col&quot;</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.email.label_tag</span> <span class=\"cp\">}}</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">form.email.help_text</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;helptext&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.email.auto_id</span> <span class=\"cp\">}}</span><span class=\"s\">_helptext&quot;</span><span class=\"p\">&gt;</span>\n          <span class=\"cp\">{{</span> <span class=\"nv\">form.email.help_text</span><span class=\"o\">|</span><span class=\"nf\">safe</span> <span class=\"cp\">}}</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.email.errors</span> <span class=\"cp\">}}</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.email</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;col&quot;</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.password.label_tag</span> <span class=\"cp\">}}</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">form.password.help_text</span> <span class=\"cp\">%}</span>\n        <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;helptext&quot;</span> <span class=\"na\">id</span><span class=\"o\">=</span><span class=\"s\">&quot;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.password.auto_id</span> <span class=\"cp\">}}</span><span class=\"s\">_helptext&quot;</span><span class=\"p\">&gt;</span>\n          <span class=\"cp\">{{</span> <span class=\"nv\">form.password.help_text</span><span class=\"o\">|</span><span class=\"nf\">safe</span> <span class=\"cp\">}}</span>\n        <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n      <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.password.errors</span> <span class=\"cp\">}}</span>\n      <span class=\"cp\">{{</span> <span class=\"nv\">form.password</span> <span class=\"cp\">}}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p>Can now be simplified to:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n...\n<span class=\"p\">&lt;</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"cp\">{{</span> <span class=\"nv\">form.name.as_field_group</span> <span class=\"cp\">}}</span>\n  <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;row&quot;</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;col&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.email.as_field_group</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">div</span> <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;col&quot;</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">form.password.as_field_group</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n  <span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n<span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n...\n<span class=\"p\">&lt;/</span><span class=\"nt\">form</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/en/dev/ref/forms/api/#django.forms.BoundField.as_field_group\" title=\"django.forms.BoundField.as_field_group\"><code class=\"xref py py-meth docutils literal notranslate\">as_field_group()</code></a> renders fields with the\n<code class=\"docutils literal notranslate\">&quot;django/forms/field.html&quot;</code> template by default and can be customized on a\nper-project, per-field, or per-request basis. See\n<a class=\"reference internal\" href=\"/en/dev/topics/forms/#reusable-field-group-templates\"><span class=\"std std-ref\">Reusable field group templates</span></a>.</p>\n</section>\n<section id=\"database-computed-default-values\">\n<h3>Database-computed default values<a class=\"heading-anchor\" href=\"#database-computed-default-values\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.Field.db_default\" title=\"django.db.models.Field.db_default\"><code class=\"xref py py-attr docutils literal notranslate\">Field.db_default</code></a> parameter\nsets a database-computed default value. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> Now<span class=\"p\">,</span> Pi\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    age <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>db_default<span class=\"o\">=</span><span class=\"mi\">18</span><span class=\"p\">)</span>\n    created <span class=\"o\">=</span> models<span class=\"o\">.</span>DateTimeField<span class=\"p\">(</span>db_default<span class=\"o\">=</span>Now<span class=\"p\">())</span>\n    circumference <span class=\"o\">=</span> models<span class=\"o\">.</span>FloatField<span class=\"p\">(</span>db_default<span class=\"o\">=</span><span class=\"mi\">2</span> <span class=\"o\">*</span> Pi<span class=\"p\">())</span>\n</code></pre></div>\n</section>\n<section id=\"database-generated-model-field\">\n<h3>Database generated model field<a class=\"heading-anchor\" href=\"#database-generated-model-field\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.GeneratedField\" title=\"django.db.models.GeneratedField\"><code class=\"xref py py-class docutils literal notranslate\">GeneratedField</code></a> allows creation of database\ngenerated columns. This field can be used on all supported database backends\nto create a field that is always computed from other fields. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> F\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Square</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    side <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n    area <span class=\"o\">=</span> models<span class=\"o\">.</span>GeneratedField<span class=\"p\">(</span>\n        expression<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s2\">&quot;side&quot;</span><span class=\"p\">)</span> <span class=\"o\">*</span> F<span class=\"p\">(</span><span class=\"s2\">&quot;side&quot;</span><span class=\"p\">),</span>\n        output_field<span class=\"o\">=</span>models<span class=\"o\">.</span>BigIntegerField<span class=\"p\">(),</span>\n        db_persist<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"more-options-for-declaring-field-choices\">\n<h3>More options for declaring field choices<a class=\"heading-anchor\" href=\"#more-options-for-declaring-field-choices\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.Field.choices\" title=\"django.db.models.Field.choices\"><code class=\"xref py py-attr docutils literal notranslate\">Field.choices</code></a> <em>(for model fields)</em> and <a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.ChoiceField.choices\" title=\"django.forms.ChoiceField.choices\"><code class=\"xref py py-attr docutils literal notranslate\">ChoiceField.choices</code></a>\n<em>(for form fields)</em> allow for more flexibility when declaring their values. In\nprevious versions of Django, <code class=\"docutils literal notranslate\">choices</code> should either be a list of 2-tuples,\nor an <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#field-choices-enum-types\"><span class=\"std std-ref\">Enumeration types</span></a> subclass, but the latter required\naccessing the <code class=\"docutils literal notranslate\">.choices</code> attribute to provide the values in the expected\nform:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\nMedal <span class=\"o\">=</span> models<span class=\"o\">.</span>TextChoices<span class=\"p\">(</span><span class=\"s2\">&quot;Medal&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;GOLD SILVER BRONZE&quot;</span><span class=\"p\">)</span>\n\nSPORT_CHOICES <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"p\">(</span><span class=\"s2\">&quot;Martial Arts&quot;</span><span class=\"p\">,</span> <span class=\"p\">[(</span><span class=\"s2\">&quot;judo&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Judo&quot;</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"s2\">&quot;karate&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Karate&quot;</span><span class=\"p\">)]),</span>\n    <span class=\"p\">(</span><span class=\"s2\">&quot;Racket&quot;</span><span class=\"p\">,</span> <span class=\"p\">[(</span><span class=\"s2\">&quot;badminton&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Badminton&quot;</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"s2\">&quot;tennis&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Tennis&quot;</span><span class=\"p\">)]),</span>\n    <span class=\"p\">(</span><span class=\"s2\">&quot;unknown&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Unknown&quot;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Winner</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    medal <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">,</span> choices<span class=\"o\">=</span>Medal<span class=\"o\">.</span>choices<span class=\"p\">)</span>\n    sport <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">,</span> choices<span class=\"o\">=</span>SPORT_CHOICES<span class=\"p\">)</span>\n</code></pre></div>\n<p>Django 5.0 adds support for accepting a mapping or a callable instead of an\niterable, and also no longer requires <code class=\"docutils literal notranslate\">.choices</code> to be used directly to\nexpand <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#field-choices-enum-types\"><span class=\"std std-ref\">enumeration types</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\nMedal <span class=\"o\">=</span> models<span class=\"o\">.</span>TextChoices<span class=\"p\">(</span><span class=\"s2\">&quot;Medal&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;GOLD SILVER BRONZE&quot;</span><span class=\"p\">)</span>\n\nSPORT_CHOICES <span class=\"o\">=</span> <span class=\"p\">{</span>  <span class=\"c1\"># Using a mapping instead of a list of 2-tuples.</span>\n    <span class=\"s2\">&quot;Martial Arts&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;judo&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Judo&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;karate&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Karate&quot;</span><span class=\"p\">},</span>\n    <span class=\"s2\">&quot;Racket&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;badminton&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Badminton&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;tennis&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Tennis&quot;</span><span class=\"p\">},</span>\n    <span class=\"s2\">&quot;unknown&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Unknown&quot;</span><span class=\"p\">,</span>\n<span class=\"p\">}</span>\n\n\n<span class=\"k\">def</span> <span class=\"nf\">get_scores</span><span class=\"p\">():</span>\n    <span class=\"k\">return</span> <span class=\"p\">[(</span>i<span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">(</span>i<span class=\"p\">))</span> <span class=\"k\">for</span> i <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"mi\">10</span><span class=\"p\">)]</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Winner</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    medal <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">,</span> choices<span class=\"o\">=</span>Medal<span class=\"p\">)</span>  <span class=\"c1\"># Using `.choices` not required.</span>\n    sport <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">,</span> choices<span class=\"o\">=</span>SPORT_CHOICES<span class=\"p\">)</span>\n    score <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>choices<span class=\"o\">=</span>get_scores<span class=\"p\">)</span>  <span class=\"c1\"># A callable is allowed.</span>\n</code></pre></div>\n<p>Under the hood the provided <code class=\"docutils literal notranslate\">choices</code> are normalized into a list of 2-tuples\nas the canonical form whenever the <code class=\"docutils literal notranslate\">choices</code> value is updated. For more\ninformation, please check the <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#field-choices\"><span class=\"std std-ref\">model field reference on choices</span></a>.</p>\n</section>\n<section id=\"minor-features\">\n<h3>Minor features<a class=\"heading-anchor\" href=\"#minor-features\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<section id=\"django-contrib-admin\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.admin</code></a><a class=\"heading-anchor\" href=\"#django-contrib-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite.get_log_entries\" title=\"django.contrib.admin.AdminSite.get_log_entries\"><code class=\"xref py py-meth docutils literal notranslate\">AdminSite.get_log_entries()</code></a> method allows customizing the\nqueryset for the site’s listed log entries.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.admin.AllValuesFieldListFilter</code>,\n<code class=\"docutils literal notranslate\">ChoicesFieldListFilter</code>, <code class=\"docutils literal notranslate\">RelatedFieldListFilter</code>, and\n<code class=\"docutils literal notranslate\">RelatedOnlyFieldListFilter</code> admin filters now handle multi-valued query\nparameters.</p></li>\n<li><p><code class=\"docutils literal notranslate\">XRegExp</code> is upgraded from version 3.2.0 to 5.1.1.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite.get_model_admin\" title=\"django.contrib.admin.AdminSite.get_model_admin\"><code class=\"xref py py-meth docutils literal notranslate\">AdminSite.get_model_admin()</code></a> method returns an admin class for\nthe given model class.</p></li>\n<li><p>Properties in <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display\" title=\"django.contrib.admin.ModelAdmin.list_display\"><code class=\"xref py py-attr docutils literal notranslate\">ModelAdmin.list_display</code></a> now support <code class=\"docutils literal notranslate\">boolean</code>\nattribute.</p></li>\n<li><p>jQuery is upgraded from version 3.6.4 to 3.7.1.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-auth\">\n<h4><a class=\"reference internal\" href=\"/en/dev/topics/auth/#module-django.contrib.auth\" title=\"django.contrib.auth: Django's authentication framework.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth</code></a><a class=\"heading-anchor\" href=\"#django-contrib-auth\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The default iteration count for the PBKDF2 password hasher is increased from\n600,000 to 720,000.</p></li>\n<li><p>The new asynchronous functions are now provided, using an\n<code class=\"docutils literal notranslate\">a</code> prefix: <a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.aauthenticate\" title=\"django.contrib.auth.aauthenticate\"><code class=\"xref py py-func docutils literal notranslate\">django.contrib.auth.aauthenticate()</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.aget_user\" title=\"django.contrib.auth.aget_user\"><code class=\"xref py py-func docutils literal notranslate\">aget_user()</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.alogin\" title=\"django.contrib.auth.alogin\"><code class=\"xref py py-func docutils literal notranslate\">alogin()</code></a>, <a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.alogout\" title=\"django.contrib.auth.alogout\"><code class=\"xref py py-func docutils literal notranslate\">alogout()</code></a>,\nand <a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.aupdate_session_auth_hash\" title=\"django.contrib.auth.aupdate_session_auth_hash\"><code class=\"xref py py-func docutils literal notranslate\">aupdate_session_auth_hash()</code></a>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">AuthenticationMiddleware</code> now adds an <a class=\"reference internal\" href=\"/en/dev/ref/request-response/#django.http.HttpRequest.auser\" title=\"django.http.HttpRequest.auser\"><code class=\"xref py py-meth docutils literal notranslate\">HttpRequest.auser()</code></a>\nasynchronous method that returns the currently logged-in user.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/auth/passwords/#django.contrib.auth.hashers.acheck_password\" title=\"django.contrib.auth.hashers.acheck_password\"><code class=\"xref py py-func docutils literal notranslate\">django.contrib.auth.hashers.acheck_password()</code></a> asynchronous\nfunction and <a class=\"reference internal\" href=\"/en/dev/topics/auth/customizing/#django.contrib.auth.models.AbstractBaseUser.acheck_password\" title=\"django.contrib.auth.models.AbstractBaseUser.acheck_password\"><code class=\"xref py py-meth docutils literal notranslate\">AbstractBaseUser.acheck_password()</code></a> method allow\nasynchronous checking of user passwords.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-contenttypes\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/contenttypes/#module-django.contrib.contenttypes\" title=\"django.contrib.contenttypes: Provides generic interface to installed models.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.contenttypes</code></a><a class=\"heading-anchor\" href=\"#django-contrib-contenttypes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related\" title=\"django.db.models.query.QuerySet.prefetch_related\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.prefetch_related()</code></a> now supports prefetching\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey\" title=\"django.contrib.contenttypes.fields.GenericForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">GenericForeignKey</code></a> with\nnon-homogeneous set of results.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-gis\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/#module-django.contrib.gis\" title=\"django.contrib.gis: Geographic Information System (GIS) extensions for Django\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.gis</code></a><a class=\"heading-anchor\" href=\"#django-contrib-gis\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/functions/#django.contrib.gis.db.models.functions.ClosestPoint\" title=\"django.contrib.gis.db.models.functions.ClosestPoint\"><code class=\"xref py py-class docutils literal notranslate\">ClosestPoint()</code></a>\nfunction returns a 2-dimensional point on the geometry that is closest to\nanother geometry.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geoquerysets/#gis-aggregation-functions\"><span class=\"std std-ref\">GIS aggregates</span></a> now support the <code class=\"docutils literal notranslate\">filter</code>\nargument.</p></li>\n<li><p>Support for GDAL 3.7 and GEOS 3.12 is added.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geos/#django.contrib.gis.geos.GEOSGeometry.equals_identical\" title=\"django.contrib.gis.geos.GEOSGeometry.equals_identical\"><code class=\"xref py py-meth docutils literal notranslate\">GEOSGeometry.equals_identical()</code></a> method allows point-wise\nequivalence checking of geometries.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-messages\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/messages/#module-django.contrib.messages\" title=\"django.contrib.messages: Provides cookie- and session-based temporary message storage.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.messages</code></a><a class=\"heading-anchor\" href=\"#django-contrib-messages\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/messages/#django.contrib.messages.test.MessagesTestMixin.assertMessages\" title=\"django.contrib.messages.test.MessagesTestMixin.assertMessages\"><code class=\"xref py py-meth docutils literal notranslate\">MessagesTestMixin.assertMessages()</code></a> assertion method allows\ntesting <a class=\"reference internal\" href=\"/en/dev/ref/contrib/messages/#module-django.contrib.messages\" title=\"django.contrib.messages: Provides cookie- and session-based temporary message storage.\"><code class=\"xref py py-mod docutils literal notranslate\">messages</code></a> added to a\n<a class=\"reference internal\" href=\"/en/dev/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\">response</code></a>.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-postgres\">\n<h4><a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/#module-django.contrib.postgres\" title=\"django.contrib.postgres: PostgreSQL-specific fields and features\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.postgres</code></a><a class=\"heading-anchor\" href=\"#django-contrib-postgres\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/constraints/#django.contrib.postgres.constraints.ExclusionConstraint.violation_error_code\" title=\"django.contrib.postgres.constraints.ExclusionConstraint.violation_error_code\"><code class=\"xref py py-attr docutils literal notranslate\">violation_error_code</code></a> attribute of\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/postgres/constraints/#django.contrib.postgres.constraints.ExclusionConstraint\" title=\"django.contrib.postgres.constraints.ExclusionConstraint\"><code class=\"xref py py-class docutils literal notranslate\">ExclusionConstraint</code></a> allows\ncustomizing the <code class=\"docutils literal notranslate\">code</code> of <code class=\"docutils literal notranslate\">ValidationError</code> raised during\n<a class=\"reference internal\" href=\"/en/dev/ref/models/instances/#validating-objects\"><span class=\"std std-ref\">model validation</span></a>.</p></li>\n</ul>\n</section>\n<section id=\"asynchronous-views\">\n<h4>Asynchronous views<a class=\"heading-anchor\" href=\"#asynchronous-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Under ASGI, <code class=\"docutils literal notranslate\">http.disconnect</code> events are now handled. This allows views to\nperform any necessary cleanup if a client disconnects before the response is\ngenerated. See <a class=\"reference internal\" href=\"/en/dev/topics/async/#async-handling-disconnect\"><span class=\"std std-ref\">Handling disconnects</span></a> for more details.</p></li>\n</ul>\n</section>\n<section id=\"decorators\">\n<h4>Decorators<a class=\"heading-anchor\" href=\"#decorators\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The following decorators now support wrapping asynchronous view functions:</p>\n<ul>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\">cache_control()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.cache.never_cache\" title=\"django.views.decorators.cache.never_cache\"><code class=\"xref py py-func docutils literal notranslate\">never_cache()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.common.no_append_slash\" title=\"django.views.decorators.common.no_append_slash\"><code class=\"xref py py-func docutils literal notranslate\">no_append_slash()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\">csrf_exempt()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\">csrf_protect()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\">ensure_csrf_cookie()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/csrf/#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\">requires_csrf_token()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/howto/error-reporting/#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_variables()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/howto/error-reporting/#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_post_parameters()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.gzip.gzip_page\" title=\"django.views.decorators.gzip.gzip_page\"><code class=\"xref py py-func docutils literal notranslate\">gzip_page()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.condition\" title=\"django.views.decorators.http.condition\"><code class=\"xref py py-func docutils literal notranslate\">condition()</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">conditional_page()</code></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.etag\" title=\"django.views.decorators.http.etag\"><code class=\"xref py py-func docutils literal notranslate\">etag()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.last_modified\" title=\"django.views.decorators.http.last_modified\"><code class=\"xref py py-func docutils literal notranslate\">last_modified()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.require_http_methods\" title=\"django.views.decorators.http.require_http_methods\"><code class=\"xref py py-func docutils literal notranslate\">require_http_methods()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.require_GET\" title=\"django.views.decorators.http.require_GET\"><code class=\"xref py py-func docutils literal notranslate\">require_GET()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.require_POST\" title=\"django.views.decorators.http.require_POST\"><code class=\"xref py py-func docutils literal notranslate\">require_POST()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.http.require_safe\" title=\"django.views.decorators.http.require_safe\"><code class=\"xref py py-func docutils literal notranslate\">require_safe()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie\" title=\"django.views.decorators.vary.vary_on_cookie\"><code class=\"xref py py-func docutils literal notranslate\">vary_on_cookie()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/http/decorators/#django.views.decorators.vary.vary_on_headers\" title=\"django.views.decorators.vary.vary_on_headers\"><code class=\"xref py py-func docutils literal notranslate\">vary_on_headers()</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_deny()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_sameorigin()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_exempt()</code></p></li>\n</ul>\n</li>\n</ul>\n</section>\n<section id=\"error-reporting\">\n<h4>Error Reporting<a class=\"heading-anchor\" href=\"#error-reporting\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/howto/error-reporting/#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_variables()</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/howto/error-reporting/#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_post_parameters()</code></a> can now be\nused with asynchronous functions.</p></li>\n</ul>\n</section>\n<section id=\"file-storage\">\n<h4>File Storage<a class=\"heading-anchor\" href=\"#file-storage\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/files/file/#django.core.files.File.open\" title=\"django.core.files.File.open\"><code class=\"xref py py-meth docutils literal notranslate\">File.open()</code></a> now passes all positional (<code class=\"docutils literal notranslate\">*args</code>) and keyword\narguments (<code class=\"docutils literal notranslate\">**kwargs</code>) to Python’s built-in <a class=\"reference external\" href=\"https://docs.python.org/3/library/functions.html#open\" title=\"(in Python v3.14)\"><code class=\"docutils literal notranslate\">open()</code></a>.</p></li>\n</ul>\n</section>\n<section id=\"forms\">\n<h4>Forms<a class=\"heading-anchor\" href=\"#forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.URLField.assume_scheme\" title=\"django.forms.URLField.assume_scheme\"><code class=\"xref py py-attr docutils literal notranslate\">assume_scheme</code></a> argument for\n<a class=\"reference internal\" href=\"/en/dev/ref/forms/fields/#django.forms.URLField\" title=\"django.forms.URLField\"><code class=\"xref py py-class docutils literal notranslate\">URLField</code></a> allows specifying a default URL scheme.</p></li>\n<li><p>In order to improve accessibility, the following changes are made:</p>\n<ul>\n<li><p>Form fields now include the <code class=\"docutils literal notranslate\">aria-describedby</code> HTML attribute to enable\nscreen readers to associate form fields with their help text.</p></li>\n<li><p>Invalid form fields now include the <code class=\"docutils literal notranslate\">aria-invalid=&quot;true&quot;</code> HTML attribute.</p></li>\n</ul>\n</li>\n</ul>\n</section>\n<section id=\"internationalization\">\n<h4>Internationalization<a class=\"heading-anchor\" href=\"#internationalization\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Support and translations for the Uyghur language are now available.</p></li>\n</ul>\n</section>\n<section id=\"migrations\">\n<h4>Migrations<a class=\"heading-anchor\" href=\"#migrations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>Serialization of functions decorated with <a class=\"reference external\" href=\"https://docs.python.org/3/library/functools.html#functools.cache\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">functools.cache()</code></a> or\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/functools.html#functools.lru_cache\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">functools.lru_cache()</code></a> is now supported without the need to write a\ncustom serializer.</p></li>\n</ul>\n</section>\n<section id=\"models\">\n<h4>Models<a class=\"heading-anchor\" href=\"#models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <code class=\"docutils literal notranslate\">create_defaults</code> argument of <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.update_or_create\" title=\"django.db.models.query.QuerySet.update_or_create\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.update_or_create()</code></a>\nand <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.aupdate_or_create\" title=\"django.db.models.query.QuerySet.aupdate_or_create\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.aupdate_or_create()</code></a> methods allows specifying a different\nfield values for the create operation.</p></li>\n<li><p>The new <code class=\"docutils literal notranslate\">violation_error_code</code> attribute of\n<a class=\"reference internal\" href=\"/en/dev/ref/models/constraints/#django.db.models.BaseConstraint\" title=\"django.db.models.BaseConstraint\"><code class=\"xref py py-class docutils literal notranslate\">BaseConstraint</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/constraints/#django.db.models.CheckConstraint\" title=\"django.db.models.CheckConstraint\"><code class=\"xref py py-class docutils literal notranslate\">CheckConstraint</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/ref/models/constraints/#django.db.models.UniqueConstraint\" title=\"django.db.models.UniqueConstraint\"><code class=\"xref py py-class docutils literal notranslate\">UniqueConstraint</code></a> allows customizing the <code class=\"docutils literal notranslate\">code</code>\nof <code class=\"docutils literal notranslate\">ValidationError</code> raised during\n<a class=\"reference internal\" href=\"/en/dev/ref/models/instances/#validating-objects\"><span class=\"std std-ref\">model validation</span></a>.</p></li>\n<li><p>The <a class=\"reference internal\" href=\"/en/dev/ref/models/instances/#ref-models-force-insert\"><span class=\"std std-ref\">force_insert</span></a> argument of\n<a class=\"reference internal\" href=\"/en/dev/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">Model.save()</code></a> now allows specifying a tuple of parent classes that must\nbe forced to be inserted.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create\" title=\"django.db.models.query.QuerySet.bulk_create\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.bulk_create()</code></a> and <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.abulk_create\" title=\"django.db.models.query.QuerySet.abulk_create\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.abulk_create()</code></a> methods now\nset the primary key on each model instance when the <code class=\"docutils literal notranslate\">update_conflicts</code>\nparameter is enabled (if the database supports it).</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/constraints/#django.db.models.UniqueConstraint.nulls_distinct\" title=\"django.db.models.UniqueConstraint.nulls_distinct\"><code class=\"xref py py-attr docutils literal notranslate\">UniqueConstraint.nulls_distinct</code></a> attribute allows customizing\nthe treatment of <code class=\"docutils literal notranslate\">NULL</code> values on PostgreSQL 15+.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/http/shortcuts/#django.shortcuts.aget_object_or_404\" title=\"django.shortcuts.aget_object_or_404\"><code class=\"xref py py-func docutils literal notranslate\">aget_object_or_404()</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/topics/http/shortcuts/#django.shortcuts.aget_list_or_404\" title=\"django.shortcuts.aget_list_or_404\"><code class=\"xref py py-func docutils literal notranslate\">aget_list_or_404()</code></a> asynchronous shortcuts allow\nasynchronous getting objects.</p></li>\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.aprefetch_related_objects\" title=\"django.db.models.aprefetch_related_objects\"><code class=\"xref py py-func docutils literal notranslate\">aprefetch_related_objects()</code></a> function allows\nasynchronous prefetching of model instances.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.aiterator\" title=\"django.db.models.query.QuerySet.aiterator\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.aiterator()</code></a> now supports previous calls to\n<code class=\"docutils literal notranslate\">prefetch_related()</code>.</p></li>\n<li><p>On MariaDB 10.7+, <code class=\"docutils literal notranslate\">UUIDField</code> is now created as <code class=\"docutils literal notranslate\">UUID</code> column rather than\n<code class=\"docutils literal notranslate\">CHAR(32)</code> column. See the migration guide above for more details on\n<a class=\"reference internal\" href=\"#migrating-uuidfield\"><span class=\"std std-ref\">Migrating existing UUIDField on MariaDB 10.7+</span></a>.</p></li>\n<li><p>Django now supports <a class=\"reference external\" href=\"https://oracle.github.io/python-oracledb/\">oracledb</a> version 1.3.2 or higher. Support for\n<code class=\"docutils literal notranslate\">cx_Oracle</code> is deprecated as of this release and will be removed in Django\n6.0.</p></li>\n</ul>\n</section>\n<section id=\"pagination\">\n<h4>Pagination<a class=\"heading-anchor\" href=\"#pagination\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/paginator/#django.core.paginator.Paginator.error_messages\" title=\"django.core.paginator.Paginator.error_messages\"><code class=\"xref py py-attr docutils literal notranslate\">django.core.paginator.Paginator.error_messages</code></a> argument\nallows customizing the error messages raised by <a class=\"reference internal\" href=\"/en/dev/ref/paginator/#django.core.paginator.Paginator.page\" title=\"django.core.paginator.Paginator.page\"><code class=\"xref py py-meth docutils literal notranslate\">Paginator.page()</code></a>.</p></li>\n</ul>\n</section>\n<section id=\"signals\">\n<h4>Signals<a class=\"heading-anchor\" href=\"#signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/topics/signals/#django.dispatch.Signal.asend\" title=\"django.dispatch.Signal.asend\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.asend()</code></a> and <a class=\"reference internal\" href=\"/en/dev/topics/signals/#django.dispatch.Signal.asend_robust\" title=\"django.dispatch.Signal.asend_robust\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.asend_robust()</code></a> methods allow\nasynchronous signal dispatch. Signal receivers may be synchronous or\nasynchronous, and will be automatically adapted to the correct calling style.</p></li>\n</ul>\n</section>\n<section id=\"templates\">\n<h4>Templates<a class=\"heading-anchor\" href=\"#templates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatefilter-escapeseq\"><code class=\"xref std std-tfilter docutils literal notranslate\">escapeseq</code></a> template filter applies <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatefilter-escape\"><code class=\"xref std std-tfilter docutils literal notranslate\">escape</code></a> to\neach element of a sequence.</p></li>\n</ul>\n</section>\n<section id=\"tests\">\n<h4>Tests<a class=\"heading-anchor\" href=\"#tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client\" title=\"django.test.Client\"><code class=\"xref py py-class docutils literal notranslate\">Client</code></a> and <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.AsyncClient\" title=\"django.test.AsyncClient\"><code class=\"xref py py-class docutils literal notranslate\">AsyncClient</code></a> now\nprovide asynchronous methods, using an <code class=\"docutils literal notranslate\">a</code> prefix:\n<a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client.asession\" title=\"django.test.Client.asession\"><code class=\"xref py py-meth docutils literal notranslate\">asession()</code></a>, <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client.alogin\" title=\"django.test.Client.alogin\"><code class=\"xref py py-meth docutils literal notranslate\">alogin()</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client.aforce_login\" title=\"django.test.Client.aforce_login\"><code class=\"xref py py-meth docutils literal notranslate\">aforce_login()</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.Client.alogout\" title=\"django.test.Client.alogout\"><code class=\"xref py py-meth docutils literal notranslate\">alogout()</code></a>.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#django.test.AsyncClient\" title=\"django.test.AsyncClient\"><code class=\"xref py py-class docutils literal notranslate\">AsyncClient</code></a> now supports the <code class=\"docutils literal notranslate\">follow</code> parameter.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/topics/testing/advanced/#django.test.runner.DiscoverRunner\" title=\"django.test.runner.DiscoverRunner\"><code class=\"xref py py-class docutils literal notranslate\">DiscoverRunner</code></a> now allows showing the duration\nof the slowest tests using the <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#cmdoption-test-durations\"><code class=\"xref std std-option docutils literal notranslate\">test --durations</code></a> option (available\non Python 3.12+).</p></li>\n</ul>\n</section>\n<section id=\"validators\">\n<h4>Validators<a class=\"heading-anchor\" href=\"#validators\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<ul class=\"simple\">\n<li><p>The new <code class=\"docutils literal notranslate\">offset</code> argument of\n<a class=\"reference internal\" href=\"/en/dev/ref/validators/#django.core.validators.StepValueValidator\" title=\"django.core.validators.StepValueValidator\"><code class=\"xref py py-class docutils literal notranslate\">StepValueValidator</code></a> allows specifying an\noffset for valid values.</p></li>\n</ul>\n</section>\n</section>\n</section>\n<section id=\"backwards-incompatible-changes-in-5-0\">\n<span id=\"backwards-incompatible-5-0\"></span><h2>Backwards incompatible changes in 5.0<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes-in-5-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"database-backend-api\">\n<h3>Database backend API<a class=\"heading-anchor\" href=\"#database-backend-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>This section describes changes that may be needed in third-party database\nbackends.</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">DatabaseFeatures.supports_expression_defaults</code> should be set to <code class=\"docutils literal notranslate\">False</code>\nif the database doesn’t support using database functions as defaults.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseFeatures.supports_default_keyword_in_insert</code> should be set to\n<code class=\"docutils literal notranslate\">False</code> if the database doesn’t support the <code class=\"docutils literal notranslate\">DEFAULT</code> keyword in\n<code class=\"docutils literal notranslate\">INSERT</code> queries.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseFeatures.supports_default_keyword_in_bulk_insert</code> should be set to\n<code class=\"docutils literal notranslate\">False</code> if the database doesn’t support the <code class=\"docutils literal notranslate\">DEFAULT</code> keyword in bulk\n<code class=\"docutils literal notranslate\">INSERT</code> queries.</p></li>\n</ul>\n</section>\n<section id=\"id1\">\n<h3><a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/#module-django.contrib.gis\" title=\"django.contrib.gis: Geographic Information System (GIS) extensions for Django\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.gis</code></a><a class=\"heading-anchor\" href=\"#id1\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>Support for GDAL 2.2 and 2.3 is removed.</p></li>\n<li><p>Support for GEOS 3.6 and 3.7 is removed.</p></li>\n</ul>\n</section>\n<section id=\"django-contrib-sitemaps\">\n<h3><a class=\"reference internal\" href=\"/en/dev/ref/contrib/sitemaps/#module-django.contrib.sitemaps\" title=\"django.contrib.sitemaps: A framework for generating Google sitemap XML files.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.sitemaps</code></a><a class=\"heading-anchor\" href=\"#django-contrib-sitemaps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.sitemaps.ping_google()</code> function and the\n<code class=\"docutils literal notranslate\">ping_google</code> management command are removed as the Google\nSitemaps ping endpoint is deprecated and will be removed in January 2024.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.sitemaps.SitemapNotFound</code> exception class is removed.</p></li>\n</ul>\n</section>\n<section id=\"dropped-support-for-mysql-8-0-11\">\n<h3>Dropped support for MySQL &lt; 8.0.11<a class=\"heading-anchor\" href=\"#dropped-support-for-mysql-8-0-11\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Support for pre-releases of MySQL 8.0.x series is removed. Django 5.0 supports\nMySQL 8.0.11 and higher.</p>\n</section>\n<section id=\"using-create-defaults-exact-may-now-be-required-with-queryset-update-or-create\">\n<h3>Using <code class=\"docutils literal notranslate\">create_defaults__exact</code> may now be required with <code class=\"docutils literal notranslate\">QuerySet.update_or_create()</code><a class=\"heading-anchor\" href=\"#using-create-defaults-exact-may-now-be-required-with-queryset-update-or-create\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.update_or_create\" title=\"django.db.models.query.QuerySet.update_or_create\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.update_or_create()</code></a> now supports the parameter\n<code class=\"docutils literal notranslate\">create_defaults</code>. As a consequence, any models that have a field named\n<code class=\"docutils literal notranslate\">create_defaults</code> that are used with an <code class=\"docutils literal notranslate\">update_or_create()</code> should specify\nthe field in the lookup with <code class=\"docutils literal notranslate\">create_defaults__exact</code>.</p>\n</section>\n<section id=\"migrating-existing-uuidfield-on-mariadb-10-7\">\n<span id=\"migrating-uuidfield\"></span><h3>Migrating existing <code class=\"docutils literal notranslate\">UUIDField</code> on MariaDB 10.7+<a class=\"heading-anchor\" href=\"#migrating-existing-uuidfield-on-mariadb-10-7\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>On MariaDB 10.7+, <code class=\"docutils literal notranslate\">UUIDField</code> is now created as <code class=\"docutils literal notranslate\">UUID</code> column rather than\n<code class=\"docutils literal notranslate\">CHAR(32)</code> column. As a consequence, any <code class=\"docutils literal notranslate\">UUIDField</code> created in\nDjango &lt; 5.0 should be replaced with a <code class=\"docutils literal notranslate\">UUIDField</code> subclass backed by\n<code class=\"docutils literal notranslate\">CHAR(32)</code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Char32UUIDField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>UUIDField<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;char(32)&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n        value <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_db_prep_value<span class=\"p\">(</span>value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"p\">)</span>\n        <span class=\"k\">if</span> value <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            value <span class=\"o\">=</span> value<span class=\"o\">.</span>hex\n        <span class=\"k\">return</span> value\n</code></pre></div>\n<p>For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    uuid <span class=\"o\">=</span> models<span class=\"o\">.</span>UUIDField<span class=\"p\">(</span>primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> default<span class=\"o\">=</span>uuid<span class=\"o\">.</span>uuid4<span class=\"p\">)</span>\n</code></pre></div>\n<p>Should become:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Char32UUIDField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>UUIDField<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    uuid <span class=\"o\">=</span> Char32UUIDField<span class=\"p\">(</span>primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> default<span class=\"o\">=</span>uuid<span class=\"o\">.</span>uuid4<span class=\"p\">)</span>\n</code></pre></div>\n<p>Running the <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\">makemigrations</code></a> command will generate a migration\ncontaining a no-op <code class=\"docutils literal notranslate\">AlterField</code> operation.</p>\n</section>\n<section id=\"miscellaneous\">\n<h3>Miscellaneous<a class=\"heading-anchor\" href=\"#miscellaneous\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">instance</code> argument of the undocumented\n<code class=\"docutils literal notranslate\">BaseModelFormSet.save_existing()</code> method is renamed to <code class=\"docutils literal notranslate\">obj</code>.</p></li>\n<li><p>The undocumented <code class=\"docutils literal notranslate\">django.contrib.admin.helpers.checkbox</code> is removed.</p></li>\n<li><p>Integer fields are now validated as 64-bit integers on SQLite to match the\nbehavior of <code class=\"docutils literal notranslate\">sqlite3</code>.</p></li>\n<li><p>The undocumented <code class=\"docutils literal notranslate\">Query.annotation_select_mask</code> attribute is changed from a\nset of strings to an ordered list of strings.</p></li>\n<li><p><code class=\"docutils literal notranslate\">ImageField.update_dimension_fields()</code> is no longer called on the\n<code class=\"docutils literal notranslate\">post_init</code> signal if <code class=\"docutils literal notranslate\">width_field</code> and <code class=\"docutils literal notranslate\">height_field</code> are not set.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/models/database-functions/#django.db.models.functions.Now\" title=\"django.db.models.functions.Now\"><code class=\"xref py py-class docutils literal notranslate\">Now</code></a> database function now uses\n<code class=\"docutils literal notranslate\">LOCALTIMESTAMP</code> instead of <code class=\"docutils literal notranslate\">CURRENT_TIMESTAMP</code> on Oracle.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite.site_header\" title=\"django.contrib.admin.AdminSite.site_header\"><code class=\"xref py py-attr docutils literal notranslate\">AdminSite.site_header</code></a> is now rendered in a <code class=\"docutils literal notranslate\">&lt;div&gt;</code> tag instead of\n<code class=\"docutils literal notranslate\">&lt;h1&gt;</code>. Screen reader users rely on heading elements for navigation within\na page. Having two <code class=\"docutils literal notranslate\">&lt;h1&gt;</code> elements was confusing and the site header wasn’t\nhelpful as it is repeated on all pages.</p></li>\n<li><p>In order to improve accessibility, the admin’s main content area and header\ncontent area are now rendered in a <code class=\"docutils literal notranslate\">&lt;main&gt;</code> and <code class=\"docutils literal notranslate\">&lt;header&gt;</code> tag instead of\n<code class=\"docutils literal notranslate\">&lt;div&gt;</code>.</p></li>\n<li><p>On databases without native support for the SQL <code class=\"docutils literal notranslate\">XOR</code> operator, <code class=\"docutils literal notranslate\">^</code> as\nthe exclusive or (<code class=\"docutils literal notranslate\">XOR</code>) operator now returns rows that are matched by an\nodd number of operands rather than exactly one operand. This is consistent\nwith the behavior of MySQL, MariaDB, and Python.</p></li>\n<li><p>The minimum supported version of <code class=\"docutils literal notranslate\">asgiref</code> is increased from 3.6.0 to\n3.7.0.</p></li>\n<li><p>The minimum supported version of <code class=\"docutils literal notranslate\">selenium</code> is increased from 3.8.0 to\n4.8.0.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">AlreadyRegistered</code> and <code class=\"docutils literal notranslate\">NotRegistered</code> exceptions are moved from\n<code class=\"docutils literal notranslate\">django.contrib.admin.sites</code> to <code class=\"docutils literal notranslate\">django.contrib.admin.exceptions</code>.</p></li>\n<li><p>The minimum supported version of SQLite is increased from 3.21.0 to 3.27.0.</p></li>\n<li><p>Support for <code class=\"docutils literal notranslate\">cx_Oracle</code> &lt; 8.3 is removed.</p></li>\n<li><p>Executing SQL queries before the app registry has been fully populated now\nraises <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#RuntimeWarning\" title=\"(in Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\">RuntimeWarning</code></a>.</p></li>\n<li><p><a class=\"reference internal\" href=\"/en/dev/ref/exceptions/#django.core.exceptions.BadRequest\" title=\"django.core.exceptions.BadRequest\"><code class=\"xref py py-exc docutils literal notranslate\">BadRequest</code></a> is raised for non-UTF-8 encoded\nrequests with the <em class=\"mimetype\">application/x-www-form-urlencoded</em> content type.\nSee <span class=\"target\" id=\"index-0\"></span><a class=\"rfc reference external\" href=\"https://datatracker.ietf.org/doc/html/rfc1866.html\"><strong>RFC 1866</strong></a> for more details.</p></li>\n<li><p>The minimum supported version of <code class=\"docutils literal notranslate\">colorama</code> is increased to 0.4.6.</p></li>\n<li><p>The minimum supported version of <code class=\"docutils literal notranslate\">docutils</code> is increased to 0.19.</p></li>\n<li><p>Filtering querysets against overflowing integer values now always returns an\nempty queryset. As a consequence, you may need to use <code class=\"docutils literal notranslate\">ExpressionWrapper()</code>\nto <a class=\"reference internal\" href=\"/en/dev/ref/models/expressions/#using-f-with-annotations\"><span class=\"std std-ref\">explicitly wrap</span></a> arithmetic against\ninteger fields in such cases.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-deprecated-in-5-0\">\n<span id=\"deprecated-features-5-0\"></span><h2>Features deprecated in 5.0<a class=\"heading-anchor\" href=\"#features-deprecated-in-5-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"id2\">\n<h3>Miscellaneous<a class=\"heading-anchor\" href=\"#id2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">DjangoDivFormRenderer</code> and <code class=\"docutils literal notranslate\">Jinja2DivFormRenderer</code> transitional form\nrenderers are deprecated.</p></li>\n<li><p>Passing positional arguments <code class=\"docutils literal notranslate\">name</code> and <code class=\"docutils literal notranslate\">violation_error_message</code> to\n<a class=\"reference internal\" href=\"/en/dev/ref/models/constraints/#django.db.models.BaseConstraint\" title=\"django.db.models.BaseConstraint\"><code class=\"xref py py-class docutils literal notranslate\">BaseConstraint</code></a> is deprecated in favor of\nkeyword-only arguments.</p></li>\n<li><p><code class=\"docutils literal notranslate\">request</code> is added to the signature of <a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.lookup_allowed\" title=\"django.contrib.admin.ModelAdmin.lookup_allowed\"><code class=\"xref py py-meth docutils literal notranslate\">ModelAdmin.lookup_allowed()</code></a>.\nSupport for <code class=\"docutils literal notranslate\">ModelAdmin</code> subclasses that do not accept this argument is\ndeprecated.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">get_joining_columns()</code> method of <code class=\"docutils literal notranslate\">ForeignObject</code> and\n<code class=\"docutils literal notranslate\">ForeignObjectRel</code> is deprecated. Starting with Django 6.0,\n<code class=\"docutils literal notranslate\">django.db.models.sql.datastructures.Join</code> will no longer fallback to\n<code class=\"docutils literal notranslate\">get_joining_columns()</code>. Subclasses should implement\n<code class=\"docutils literal notranslate\">get_joining_fields()</code> instead.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">ForeignObject.get_reverse_joining_columns()</code> method is deprecated.</p></li>\n<li><p>The default scheme for <code class=\"docutils literal notranslate\">forms.URLField</code> will change from <code class=\"docutils literal notranslate\">&quot;http&quot;</code> to\n<code class=\"docutils literal notranslate\">&quot;https&quot;</code> in Django 6.0. Set <code class=\"docutils literal notranslate\">FORMS_URLFIELD_ASSUME_HTTPS</code> transitional\nsetting to <code class=\"docutils literal notranslate\">True</code> to opt into assuming <code class=\"docutils literal notranslate\">&quot;https&quot;</code> during the Django 5.x\nrelease cycle.</p></li>\n<li><p><code class=\"docutils literal notranslate\">FORMS_URLFIELD_ASSUME_HTTPS</code> transitional setting is deprecated.</p></li>\n<li><p>Support for calling <code class=\"docutils literal notranslate\">format_html()</code> without passing args or kwargs is\ndeprecated.</p></li>\n<li><p>Support for <code class=\"docutils literal notranslate\">cx_Oracle</code> is deprecated in favor of <a class=\"reference external\" href=\"https://oracle.github.io/python-oracledb/\">oracledb</a> 1.3.2+ Python\ndriver.</p></li>\n<li><p><code class=\"docutils literal notranslate\">DatabaseOperations.field_cast_sql()</code> is deprecated in favor of\n<code class=\"docutils literal notranslate\">DatabaseOperations.lookup_cast()</code>. Starting with Django 6.0,\n<code class=\"docutils literal notranslate\">BuiltinLookup.process_lhs()</code> will no longer call <code class=\"docutils literal notranslate\">field_cast_sql()</code>.\nThird-party database backends should implement <code class=\"docutils literal notranslate\">lookup_cast()</code> instead.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.db.models.enums.ChoicesMeta</code> metaclass is renamed to\n<code class=\"docutils literal notranslate\">ChoicesType</code>.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">Prefetch.get_current_queryset()</code> method is deprecated.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">get_prefetch_queryset()</code> method of related managers and descriptors\nis deprecated. Starting with Django 6.0, <code class=\"docutils literal notranslate\">get_prefetcher()</code> and\n<code class=\"docutils literal notranslate\">prefetch_related_objects()</code> will no longer fallback to\n<code class=\"docutils literal notranslate\">get_prefetch_queryset()</code>. Subclasses should implement\n<code class=\"docutils literal notranslate\">get_prefetch_querysets()</code> instead.</p></li>\n</ul>\n</section>\n</section>\n<section id=\"features-removed-in-5-0\">\n<h2>Features removed in 5.0<a class=\"heading-anchor\" href=\"#features-removed-in-5-0\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>These features have reached the end of their deprecation cycle and are removed\nin Django 5.0.</p>\n<p>See <a class=\"reference internal\" href=\"/en/dev/releases/4.0/#deprecated-features-4-0\"><span class=\"std std-ref\">Features deprecated in 4.0</span></a> for details on these changes, including how\nto remove usage of these features.</p>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">SERIALIZE</code> test setting is removed.</p></li>\n<li><p>The undocumented <code class=\"docutils literal notranslate\">django.utils.baseconv</code> module is removed.</p></li>\n<li><p>The undocumented <code class=\"docutils literal notranslate\">django.utils.datetime_safe</code> module is removed.</p></li>\n<li><p>The default value of the <code class=\"docutils literal notranslate\">USE_TZ</code> setting is changed from <code class=\"docutils literal notranslate\">False</code> to\n<code class=\"docutils literal notranslate\">True</code>.</p></li>\n<li><p>The default sitemap protocol for sitemaps built outside the context of a\nrequest is changed from <code class=\"docutils literal notranslate\">'http'</code> to <code class=\"docutils literal notranslate\">'https'</code>.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">extra_tests</code> argument for <code class=\"docutils literal notranslate\">DiscoverRunner.build_suite()</code> and\n<code class=\"docutils literal notranslate\">DiscoverRunner.run_tests()</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.postgres.aggregates.ArrayAgg</code>, <code class=\"docutils literal notranslate\">JSONBAgg</code>, and\n<code class=\"docutils literal notranslate\">StringAgg</code> aggregates no longer return <code class=\"docutils literal notranslate\">[]</code>, <code class=\"docutils literal notranslate\">[]</code>, and <code class=\"docutils literal notranslate\">''</code>,\nrespectively, when there are no rows.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">USE_L10N</code> setting is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">USE_DEPRECATED_PYTZ</code> transitional setting is removed.</p></li>\n<li><p>Support for <code class=\"docutils literal notranslate\">pytz</code> timezones is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">is_dst</code> argument is removed from:</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">QuerySet.datetimes()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.utils.timezone.make_aware()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.Trunc()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncSecond()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncMinute()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncHour()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncDay()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncWeek()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncMonth()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncQuarter()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.db.models.functions.TruncYear()</code></p></li>\n</ul>\n</li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.gis.admin.GeoModelAdmin</code> and <code class=\"docutils literal notranslate\">OSMGeoAdmin</code> classes\nare removed.</p></li>\n<li><p>The undocumented <code class=\"docutils literal notranslate\">BaseForm._html_output()</code> method is removed.</p></li>\n<li><p>The ability to return a <code class=\"docutils literal notranslate\">str</code>, rather than a <code class=\"docutils literal notranslate\">SafeString</code>, when rendering\nan <code class=\"docutils literal notranslate\">ErrorDict</code> and <code class=\"docutils literal notranslate\">ErrorList</code> is removed.</p></li>\n</ul>\n<p>See <a class=\"reference internal\" href=\"/en/dev/releases/4.1/#deprecated-features-4-1\"><span class=\"std std-ref\">Features deprecated in 4.1</span></a> for details on these changes, including how\nto remove usage of these features.</p>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">SitemapIndexItem.__str__()</code> method is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">CSRF_COOKIE_MASKED</code> transitional setting is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">name</code> argument of <code class=\"docutils literal notranslate\">django.utils.functional.cached_property()</code> is\nremoved.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">opclasses</code> argument of\n<code class=\"docutils literal notranslate\">django.contrib.postgres.constraints.ExclusionConstraint</code> is removed.</p></li>\n<li><p>The undocumented ability to pass <code class=\"docutils literal notranslate\">errors=None</code> to\n<code class=\"docutils literal notranslate\">SimpleTestCase.assertFormError()</code> and <code class=\"docutils literal notranslate\">assertFormsetError()</code> is removed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.sessions.serializers.PickleSerializer</code> is removed.</p></li>\n<li><p>The usage of <code class=\"docutils literal notranslate\">QuerySet.iterator()</code> on a queryset that prefetches related\nobjects without providing the <code class=\"docutils literal notranslate\">chunk_size</code> argument is no longer allowed.</p></li>\n<li><p>Passing unsaved model instances to related filters is no longer allowed.</p></li>\n<li><p><code class=\"docutils literal notranslate\">created=True</code> is required in the signature of\n<code class=\"docutils literal notranslate\">RemoteUserBackend.configure_user()</code> subclasses.</p></li>\n<li><p>Support for logging out via <code class=\"docutils literal notranslate\">GET</code> requests in the\n<code class=\"docutils literal notranslate\">django.contrib.auth.views.LogoutView</code> and\n<code class=\"docutils literal notranslate\">django.contrib.auth.views.logout_then_login()</code> is removed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.utils.timezone.utc</code> alias to <code class=\"docutils literal notranslate\">datetime.timezone.utc</code> is\nremoved.</p></li>\n<li><p>Passing a response object and a form/formset name to\n<code class=\"docutils literal notranslate\">SimpleTestCase.assertFormError()</code> and <code class=\"docutils literal notranslate\">assertFormSetError()</code> is no\nlonger allowed.</p></li>\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.gis.admin.OpenLayersWidget</code> is removed.</p></li>\n</ul>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">django.contrib.auth.hashers.CryptPasswordHasher</code> is removed.</p></li>\n</ul>\n<ul class=\"simple\">\n<li><p>The <code class=\"docutils literal notranslate\">&quot;django/forms/default.html&quot;</code> and\n<code class=\"docutils literal notranslate\">&quot;django/forms/formsets/default.html&quot;</code> templates are removed.</p></li>\n<li><p>The default form and formset rendering style is changed to the div-based.</p></li>\n<li><p>Passing <code class=\"docutils literal notranslate\">nulls_first=False</code> or <code class=\"docutils literal notranslate\">nulls_last=False</code> to <code class=\"docutils literal notranslate\">Expression.asc()</code>\nand <code class=\"docutils literal notranslate\">Expression.desc()</code> methods, and the <code class=\"docutils literal notranslate\">OrderBy</code> expression is no\nlonger allowed.</p></li>\n</ul>\n</section>","rootId":"django-5-0-release-notes","toc":[{"title":"Python compatibility","anchor":"python-compatibility","children":[]},{"title":"Third-party library support for older version of Django","anchor":"third-party-library-support-for-older-version-of-django","children":[]},{"title":"What’s new in Django 5.0","anchor":"what-s-new-in-django-5-0","children":[{"title":"Facet filters in the admin","anchor":"facet-filters-in-the-admin","children":[]},{"title":"Simplified templates for form field rendering","anchor":"simplified-templates-for-form-field-rendering","children":[]},{"title":"Database-computed default values","anchor":"database-computed-default-values","children":[]},{"title":"Database generated model field","anchor":"database-generated-model-field","children":[]},{"title":"More options for declaring field choices","anchor":"more-options-for-declaring-field-choices","children":[]},{"title":"Minor features","anchor":"minor-features","children":[{"title":"django.contrib.admin","anchor":"django-contrib-admin","children":[]},{"title":"django.contrib.auth","anchor":"django-contrib-auth","children":[]},{"title":"django.contrib.contenttypes","anchor":"django-contrib-contenttypes","children":[]},{"title":"django.contrib.gis","anchor":"django-contrib-gis","children":[]},{"title":"django.contrib.messages","anchor":"django-contrib-messages","children":[]},{"title":"django.contrib.postgres","anchor":"django-contrib-postgres","children":[]},{"title":"Asynchronous views","anchor":"asynchronous-views","children":[]},{"title":"Decorators","anchor":"decorators","children":[]},{"title":"Error Reporting","anchor":"error-reporting","children":[]},{"title":"File Storage","anchor":"file-storage","children":[]},{"title":"Forms","anchor":"forms","children":[]},{"title":"Internationalization","anchor":"internationalization","children":[]},{"title":"Migrations","anchor":"migrations","children":[]},{"title":"Models","anchor":"models","children":[]},{"title":"Pagination","anchor":"pagination","children":[]},{"title":"Signals","anchor":"signals","children":[]},{"title":"Templates","anchor":"templates","children":[]},{"title":"Tests","anchor":"tests","children":[]},{"title":"Validators","anchor":"validators","children":[]}]}]},{"title":"Backwards incompatible changes in 5.0","anchor":"backwards-incompatible-changes-in-5-0","children":[{"title":"Database backend API","anchor":"database-backend-api","children":[]},{"title":"django.contrib.gis","anchor":"id1","children":[]},{"title":"django.contrib.sitemaps","anchor":"django-contrib-sitemaps","children":[]},{"title":"Dropped support for MySQL < 8.0.11","anchor":"dropped-support-for-mysql-8-0-11","children":[]},{"title":"Using create_defaults__exact may now be required with QuerySet.update_or_create()","anchor":"using-create-defaults-exact-may-now-be-required-with-queryset-update-or-create","children":[]},{"title":"Migrating existing UUIDField on MariaDB 10.7+","anchor":"migrating-existing-uuidfield-on-mariadb-10-7","children":[]},{"title":"Miscellaneous","anchor":"miscellaneous","children":[]}]},{"title":"Features deprecated in 5.0","anchor":"features-deprecated-in-5-0","children":[{"title":"Miscellaneous","anchor":"id2","children":[]}]},{"title":"Features removed in 5.0","anchor":"features-removed-in-5-0","children":[]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/5.0.1","title":"Django 5.0.1 release notes","url":"/en/dev/releases/5.0.1/"},"next":{"docname":"releases/4.2.30","title":"Django 4.2.30 release notes","url":"/en/dev/releases/4.2.30/"},"formats":{"html":"/en/dev/releases/5.0/","markdown":"/en/dev/releases/5.0.md","json":"/en/dev/releases/5.0.json"},"source":"https://github.com/django/django/blob/main/docs/releases/5.0.txt","official":"https://docs.djangoproject.com/en/dev/releases/5.0/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0"],"inLocales":["en"]}