Django 6.2 release notes - UNDER DEVELOPMENT

Expected April 2027

Welcome to Django 6.2!

These release notes cover the new features, as well as some backwards incompatible changes you should be aware of when upgrading from Django 6.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 6.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 5.2, will end in April 2028.

Python compatibility

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

What’s new in Django 6.2

Adopting calendar versioning

Following DEP 20, the releases previously planned as Django 7.0 and 7.1 are now Django 2028 and 2029. Accordingly, the deprecation warning classes are renamed to match the calendar version in which the features they mark are removed: RemovedInDjango70Warning becomes RemovedInDjango2028Warning, and RemovedInDjango71Warning becomes RemovedInDjango2029Warning.

Minor features

django.contrib.admin

  • …

django.contrib.admindocs

  • …

django.contrib.auth

  • The default iteration count for the PBKDF2 password hasher is increased from 1,500,000 to 1,800,000.

django.contrib.contenttypes

  • …

django.contrib.gis

  • DataSource now preserves millisecond precision when reading time and datetime fields.

django.contrib.messages

  • …

django.contrib.postgres

  • …

django.contrib.redirects

  • …

django.contrib.sessions

  • …

django.contrib.sitemaps

  • …

django.contrib.sites

  • …

django.contrib.staticfiles

  • …

django.contrib.syndication

  • …

Asynchronous views

  • …

Cache

  • Subclasses of BaseDatabaseCache now support culling on a percentage of writes as an optimization. The default is 10%, and may be configured using the CULL_PROBABILITY option.

CSP

  • …

CSRF

  • …

Database backends

  • …

Decorators

  • …

Email

Error Reporting

  • …

File Storage

  • …

File Uploads

  • …

Forms

  • …

Generic Views

  • …

Internationalization

  • …

Logging

  • …

Management Commands

  • The new listurls command lists the URLs from the project’s root URLconf, including the view class or function (and name, if present).

  • The makemigrations command now tracks all changes to unmanaged models, including field additions, removals, alterations, constraints, and model renames. After upgrading, you will see new migrations detected for unmanaged models that have changed since their creation.

  • Whether to suppress an ImportError escaping from a settings module is configurable by the new BaseCommand.requires_settings attribute (default True). In previous versions, such errors were always suppressed.

Migrations

  • …

Models

  • …

Requests and Responses

  • …

Security

  • …

Serialization

  • …

Signals

  • …

Tasks

  • …

Templates

  • …

Tests

URLs

  • …

Utilities

Validators

Backwards incompatible changes in 6.2

Database backend API

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

  • …

django.contrib.admin

  • The admin view_on_site URL now consistently returns an HTTP 403 response when a staff user lacks view or change permission for the target model.

  • The admin history view now checks permissions before object existence, consistently returning an HTTP 403 response for staff users without the view or change permission regardless of whether the object exists.

  • The undocumented django.contrib.admin.tests module was removed.

django.contrib.gis

  • The seconds value returned by as_datetime() is now a c_float rather than a c_int.

  • Support for PostGIS 3.2 is removed.

  • Support for GDAL 3.3 and 3.4 is removed.

  • Support for GEOS 3.10 is removed.

Models

  • Unsaved instances with a composite primary key or a db_default primary key no longer compare equal to other instances.

  • django.db.models.GenericIPAddressField now validates IPv6 input strictly when saving and querying. Invalid IPv6 addresses now raise ValidationError instead of being silently accepted, and surrounding whitespace is stripped.

Requests and responses

  • Most Django-provided middleware now set async_capable = False to avoid repetitive context switching in MiddlewareMixin.__acall__() under ASGI. For atypical use cases, e.g. high in-process concurrency over non-ORM I/O, where no thread is otherwise held, the repetitive context switching may be preferable to pinning a thread per request (see Performance). Such deployments can restore the prior behavior by setting async_capable = True; see MiddlewareMixin. RemoteUserMiddleware is unaffected, because it does not use MiddlewareMixin. Neither is LoginRequiredMiddleware nor django.contrib.admindocs.middleware.XViewMiddleware affected, as they did not implement process_request() or process_response().

Tests

  • The undocumented django.test.selenium module was removed.

Dropped support for PostgreSQL 15

Upstream support for PostgreSQL 15 ends in November 2027. Django 6.2 supports PostgreSQL 16 and higher.

Miscellaneous

  • To facilitate the deprecation of the safe parameter of JsonResponse, it now defaults to False, because the pollution vulnerability in the Array prototype was fixed in ES5.

  • DjangoJSONEncoder now omits the millisecond component of serialized datetime.datetime and datetime.time objects if they have zero milliseconds. For example, datetime.datetime(2000, 1, 1, 0, 0, 0, 1) now serializes to "2000-01-01T00:00:00" rather than "2000-01-01T00:00:00.000".

  • utils.module_loading.import_string() now deterministically favors submodules in ambiguous cases where depending on prior import state, a same-named attribute of the parent module might have been returned instead.

  • The minimum supported version of asgiref is increased from 3.9.1 to 3.12.1.

  • The minimum supported version of oracledb is increased from 2.3.0 to 4.0.2.

  • In the asynchronous request path, error responses (such as those rendered by handler404 and handler500) are now rendered on the request’s thread-sensitive thread, rather than on a shared thread pool, so that database connections used during error handling are managed by close_old_connections().

Features deprecated in 6.2

Validators

  • The undocumented EmailValidator.validate_domain_part() method is deprecated in favor of the new validate_domain() method.

Miscellaneous

  • Indexing django.VERSION from its third component on, reading it in a way which depends on its length, such as unpacking it or calling len() on it, and comparing it against three or more components are all deprecated. Under the calendar versioning adopted in DEP 20, versions are YYYY[.N] and have no minor component, so from Django 2028 django.VERSION has four components, (year, patch, status, iteration). Use the .feature, .patch, .status, and .iteration attributes, which give the same answers under both versioning schemes:

    django.VERSION.feature  # (6, 2) for 6.2.1, and (2028,) for 2028.1
    django.VERSION.patch  # 1 for both 6.2.1 and 2028.1
    

    Comparisons against one or two components, such as django.VERSION >= (6, 2), are unaffected.

  • The MiddlewareMixin class moved from django.utils.deprecation to django.middleware. The old import path is deprecated.

  • The safe parameter is deprecated from JsonResponse. Omitting the argument is equivalent to the prior safe=False usage.

  • Calling QuerySet.aiterator() after prefetch_related() without providing a chunk_size is deprecated. It currently falls back to a chunk_size of 2000, but a ValueError will be raised in Django 2029.

  • Omitting the tzinfo argument of Extract and Trunc database functions when used in migrations (for example as a db_default) and USE_TZ is True is deprecated. The timezone information is not captured during migration serialization, which can lead to inconsistent behavior if TIME_ZONE changes. Pass the tzinfo argument explicitly to suppress this warning. In Django 2029, the current timezone will be captured automatically when tzinfo is omitted.