============================================ Django 5.2 release notes - UNDER DEVELOPMENT ============================================ *Expected April 2025* Welcome to Django 5.2! These release notes cover the :ref:`new features `, as well as some :ref:`backwards incompatible changes ` you should be aware of when upgrading from Django 5.1 or earlier. We've :ref:`begun the deprecation process for some features `. See the :doc:`/howto/upgrade-version` guide if you're updating an existing project. Django 5.2 is designated as a :term:`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. .. _whats-new-5.2: What's new in Django 5.2 ======================== Minor features -------------- :mod:`django.contrib.admin` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The ``admin/base.html`` template now has a new block :ref:`extrabody ` for adding custom code before the closing ```` tag. :mod:`django.contrib.admindocs` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Links to components in docstrings now supports custom link text, using the format ``:role:`link text ```. See :ref:`documentation helpers ` for more details. :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ * The default iteration count for the PBKDF2 password hasher is increased from 870,000 to 1,000,000. * The following new asynchronous methods are now provided, using an ``a`` prefix: * :meth:`.UserManager.acreate_user` * :meth:`.UserManager.acreate_superuser` * :meth:`.BaseUserManager.aget_by_natural_key` * :meth:`.User.aget_user_permissions` * :meth:`.User.aget_all_permissions` * :meth:`.User.aget_group_permissions` * :meth:`.User.ahas_perm` * :meth:`.User.ahas_perms` * :meth:`.User.ahas_module_perms` * :meth:`.User.aget_user_permissions` * :meth:`.User.aget_group_permissions` * :meth:`.User.ahas_perm` * :meth:`.ModelBackend.aauthenticate` * :meth:`.ModelBackend.aget_user_permissions` * :meth:`.ModelBackend.aget_group_permissions` * :meth:`.ModelBackend.aget_all_permissions` * :meth:`.ModelBackend.ahas_perm` * :meth:`.ModelBackend.ahas_module_perms` * :meth:`.RemoteUserBackend.aauthenticate` * :meth:`.RemoteUserBackend.aconfigure_user` * Auth backends can now provide async implementations which are used when calling async auth functions (e.g. :func:`~.django.contrib.auth.aauthenticate`) to reduce context-switching which improves performance. See :ref:`adding an async interface ` for more details. * The :ref:`password validator classes ` now have a new method ``get_error_message()``, which can be overridden in subclasses to customize the error messages. :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.gis` ~~~~~~~~~~~~~~~~~~~~~~~~~ * GDAL now supports curved geometries ``CurvePolygon``, ``CompoundCurve``, ``CircularString``, ``MultiSurface``, and ``MultiCurve`` via the new :attr:`.OGRGeometry.has_curve` property, and the :meth:`.OGRGeometry.get_linear_geometry` and :meth:`.OGRGeometry.get_curve_geometry` methods. * :lookup:`coveredby` and :lookup:`covers` lookup are now supported on MySQL. * :lookup:`coveredby` and :lookup:`isvalid` lookups, :class:`~django.contrib.gis.db.models.Collect` aggregation, and :class:`~django.contrib.gis.db.models.functions.GeoHash` and :class:`~django.contrib.gis.db.models.functions.IsValid` database functions are now supported on MariaDB 11.7+. :mod:`django.contrib.messages` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.postgres` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.redirects` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sessions` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sitemaps` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.sites` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.staticfiles` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ... :mod:`django.contrib.syndication` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * All :class:`~django.utils.feedgenerator.SyndicationFeed` classes now support a ``stylesheets`` attribute. If specified, an ```` processing instruction will be added to the top of the document for each stylesheet in the given list. See :ref:`feed-stylesheets` for more details. Asynchronous views ~~~~~~~~~~~~~~~~~~ * ... Cache ~~~~~ * ... CSRF ~~~~ * ... Database backends ~~~~~~~~~~~~~~~~~ * ... Decorators ~~~~~~~~~~ * :func:`~django.utils.decorators.method_decorator` now supports wrapping asynchronous view methods. Email ~~~~~ * Tuple items of :class:`EmailMessage.attachments ` and :class:`EmailMultiAlternatives.attachments ` are now named tuples, as opposed to regular tuples. * :attr:`EmailMultiAlternatives.alternatives ` is now a list of named tuples, as opposed to regular tuples. * The new :meth:`~django.core.mail.EmailMultiAlternatives.body_contains` method returns a boolean indicating whether a provided text is contained in the email ``body`` and in all attached MIME type ``text/*`` alternatives. Error Reporting ~~~~~~~~~~~~~~~ * The attribute :attr:`.SafeExceptionReporterFilter.hidden_settings` now treats values as sensitive if their name includes ``AUTH``. File Storage ~~~~~~~~~~~~ * ... File Uploads ~~~~~~~~~~~~ * ... Forms ~~~~~ * The new :class:`~django.forms.ColorInput` form widget is for entering a color in ``rrggbb`` hexadecimal format and renders as ````. Some browsers support a visual color picker interface for this input type. * The new :class:`~django.forms.SearchInput` form widget is for entering search queries and renders as ````. * The new :class:`~django.forms.TelInput` form widget is for entering telephone numbers and renders as ````. Generic Views ~~~~~~~~~~~~~ * ... Internationalization ~~~~~~~~~~~~~~~~~~~~ * ... Logging ~~~~~~~ * ... Management Commands ~~~~~~~~~~~~~~~~~~~ * A new warning is printed to the console when running :djadmin:`runserver` that ``runserver`` is unsuitable for production. This warning can be hidden by setting the :envvar:`HIDE_PRODUCTION_WARNING` environment variable to ``"true"``. * The :djadmin:`makemigrations` and :djadmin:`migrate` commands have a new ``Command.autodetector`` attribute for subclasses to override in order to use a custom autodetector class. Migrations ~~~~~~~~~~ * ... Models ~~~~~~ * The ``SELECT`` clause generated when using :meth:`QuerySet.values()` and :meth:`~django.db.models.query.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 :meth:`QuerySet.union()` unpredictable. * Added support for validation of model constraints which use a :class:`~django.db.models.GeneratedField`. * The new :attr:`.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. * :attr:`CharField.max_length ` is no longer required to be set on SQLite, which supports unlimited ``VARCHAR`` columns. * :meth:`.QuerySet.explain` now supports the ``memory`` and ``serialize`` options on PostgreSQL 17+. Requests and Responses ~~~~~~~~~~~~~~~~~~~~~~ * The new :attr:`.HttpResponse.text` property provides the string representation of :attr:`.HttpResponse.content`. * The new :meth:`.HttpRequest.get_preferred_type` method can be used to query the preferred media type the client accepts. Security ~~~~~~~~ * ... Serialization ~~~~~~~~~~~~~ * Each serialization format now defines a ``Deserializer`` class, rather than a function, to improve extensibility when defining a :ref:`custom serialization format `. Signals ~~~~~~~ * ... Templates ~~~~~~~~~ * ... Tests ~~~~~ * Stack frames from Django's custom assertions are now hidden. This makes test failures easier to read and enables :option:`test --pdb` to directly enter into the failing test method. * Data loaded from :attr:`~django.test.TransactionTestCase.fixtures` and from migrations enabled with :ref:`serialized_rollback=True ` are now available during ``TransactionTestCase.setUpClass()``. URLs ~~~~ * ... Utilities ~~~~~~~~~ * :class:`~django.utils.safestring.SafeString` now returns :py:data:`NotImplemented` in ``__add__`` for non-string right-hand side values. This aligns with the :py:class:`str` addition behavior and allows ``__radd__`` to be used if available. * :func:`~django.utils.html.format_html_join` now supports taking an iterable of mappings, passing their contents as keyword arguments to :func:`~django.utils.html.format_html`. Validators ~~~~~~~~~~ * ... .. _backwards-incompatible-5.2: Backwards incompatible changes in 5.2 ===================================== Database backend API -------------------- This section describes changes that may be needed in third-party database backends. * The new :meth:`Model._is_pk_set() ` method allows checking if a Model instance's primary key is defined. :mod:`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. Miscellaneous ------------- * Adding :attr:`.EmailMultiAlternatives.alternatives` is now only supported via the :meth:`~.EmailMultiAlternatives.attach_alternative` method. * The minimum supported version of ``gettext`` is increased from 0.15 to 0.19. * ``HttpRequest.accepted_types`` is now sorted by the client's preference, based on the request's ``Accept`` header. * :attr:`.UniqueConstraint.violation_error_code` and :attr:`.UniqueConstraint.violation_error_message` are now always used when provided. Previously, these were ignored when :attr:`.UniqueConstraint.fields` were set without a :attr:`.UniqueConstraint.condition`. * The :func:`~django.template.context_processors.debug` context processor is no longer included in the default project template. * The following methods now have ``alters_data=True`` set to prevent side effects when :ref:`rendering a template context `: * :meth:`.UserManager.create_user` * :meth:`.UserManager.acreate_user` * :meth:`.UserManager.create_superuser` * :meth:`.UserManager.acreate_superuser` * :meth:`.QuerySet.create` * :meth:`.QuerySet.acreate` * :meth:`.QuerySet.bulk_create` * :meth:`.QuerySet.abulk_create` * :meth:`.QuerySet.get_or_create` * :meth:`.QuerySet.aget_or_create` * :meth:`.QuerySet.update_or_create` * :meth:`.QuerySet.aupdate_or_create` .. _deprecated-features-5.2: 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.