• Language: en
  • Documentation version: development

Django 5.2 release notes - UNDER DEVELOPMENT

Expected April 2025

Welcome to Django 5.2!

These release notes cover the new features, as well as some backwards incompatible changes you should be aware of when upgrading from Django 5.1 or earlier. We’ve begun the deprecation process for some features.

See the How to upgrade Django to a newer version guide if you’re updating an existing project.

Django 5.2 is designated as a long-term support release. It will receive security updates for at least three years after its release. Support for the previous LTS, Django 4.2, will end in April 2026.

Python compatibility

Django 5.2 supports Python 3.10, 3.11, 3.12, and 3.13. We highly recommend and only officially support the latest release of each series.

What’s new in Django 5.2

Composite Primary Keys

The new django.db.models.CompositePrimaryKey allows tables to be created with a primary key consisting of multiple fields.

To use a composite primary key, when creating a model set the pk field to be a CompositePrimaryKey:

from django.db import models


class Release(models.Model):
    pk = models.CompositePrimaryKey("version", "name")
    version = models.IntegerField()
    name = models.CharField(max_length=20)

See Composite primary keys for more details.

Minor features

django.contrib.admin

  • The admin/base.html template now has a new block extrabody for adding custom code before the closing </body> tag.

django.contrib.admindocs

  • Links to components in docstrings now supports custom link text, using the format :role:`link text <link>`. See documentation helpers for more details.

  • The model pages are now restricted to users with the corresponding view or change permissions.

django.contrib.auth

django.contrib.contenttypes

django.contrib.gis

django.contrib.messages

django.contrib.postgres

django.contrib.redirects

django.contrib.sessions

django.contrib.sitemaps

django.contrib.sites

django.contrib.staticfiles

django.contrib.syndication

  • All SyndicationFeed classes now support a stylesheets attribute. If specified, an <? xml-stylesheet ?> processing instruction will be added to the top of the document for each stylesheet in the given list. See Feed stylesheets for more details.

Asynchronous views

Cache

CSRF

Database backends

  • MySQL connections now default to using the utf8mb4 character set, instead of utf8, which is an alias for the deprecated character set utf8mb3.

Decorators

Email

Error Reporting

File Storage

File Uploads

Forms

  • The new ColorInput form widget is for entering a color in rrggbb hexadecimal format and renders as <input type="color" ...>. Some browsers support a visual color picker interface for this input type.

  • The new SearchInput form widget is for entering search queries and renders as <input type="search" ...>.

  • The new TelInput form widget is for entering telephone numbers and renders as <input type="tel" ...>.

  • The new field_id argument for ErrorList allows an HTML id attribute to be added in the error template. See ErrorList.field_id for details.

Generic Views

Internationalization

Logging

Management Commands

  • A new warning is displayed when running runserver, indicating that it is unsuitable for production. This warning can be suppressed by setting the HIDE_PRODUCTION_WARNING environment variable to "true".

  • The makemigrations and migrate commands have a new Command.autodetector attribute for subclasses to override in order to use a custom autodetector class.

Migrations

  • The new operation AlterConstraint is a no-op operation that alters constraints without dropping and recreating constraints in the database.

Models

  • The SELECT clause generated when using QuerySet.values() and QuerySet.values_list() now matches the specified order of the referenced expressions. Previously, the order was based of a set of counterintuitive rules which made query combination through methods such as QuerySet.union() unpredictable.

  • Added support for validation of model constraints which use a GeneratedField.

  • The new Expression.set_returning attribute specifies that the expression contains a set-returning function, enforcing subquery evaluation. This is necessary for many Postgres set-returning functions.

  • CharField.max_length is no longer required to be set on SQLite, which supports unlimited VARCHAR columns.

  • QuerySet.explain() now supports the memory and serialize options on PostgreSQL 17+.

Requests and Responses

Security

Serialization

  • Each serialization format now defines a Deserializer class, rather than a function, to improve extensibility when defining a custom serialization format.

Signals

Templates

  • The new simple_block_tag() decorator enables the creation of simple block tags, which can accept and use a section of the template.

Tests

  • Stack frames from Django’s custom assertions are now hidden. This makes test failures easier to read and enables test --pdb to directly enter into the failing test method.

  • Data loaded from fixtures and from migrations enabled with serialized_rollback=True are now available during TransactionTestCase.setUpClass().

URLs

Utilities

  • SafeString now returns NotImplemented in __add__ for non-string right-hand side values. This aligns with the str addition behavior and allows __radd__ to be used if available.

  • format_html_join() now supports taking an iterable of mappings, passing their contents as keyword arguments to format_html().

Validators

Backwards incompatible changes in 5.2

Database backend API

This section describes changes that may be needed in third-party database backends.

  • The new Model._is_pk_set() method allows checking if a Model instance’s primary key is defined.

  • BaseDatabaseOperations.adapt_decimalfield_value() is now a no-op, simply returning the given value.

django.contrib.gis

  • Support for PostGIS 3.0 is removed.

  • Support for GDAL 3.0 is removed.

Dropped support for PostgreSQL 13

Upstream support for PostgreSQL 13 ends in November 2025. Django 5.2 supports PostgreSQL 14 and higher.

Changed MySQL connection character set default

MySQL connections now default to using the utf8mb4 character set, instead of utf8, which is an alias for the deprecated character set utf8mb3. utf8mb3 can be specified in the OPTIONS part of the DATABASES setting, if needed for legacy databases.

Miscellaneous

Features deprecated in 5.2

Miscellaneous

  • The all argument for the django.contrib.staticfiles.finders.find() function is deprecated in favor of the find_all argument.

  • The fallback to request.user when user is None in django.contrib.auth.login() and django.contrib.auth.alogin() will be removed.

Back to Top