Django 6.0 release notes - UNDER DEVELOPMENT¶
Expected December 2025
Welcome to Django 6.0!
These release notes cover the new features, as well as some backwards incompatible changes you’ll want to be aware of when upgrading from Django 5.2 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.
Python compatibility¶
Django 6.0 supports Python 3.12 and 3.13. We highly recommend and only officially support the latest release of each series.
The Django 5.2.x series is the last to support Python 3.10 and 3.11.
Third-party library support for older version of Django¶
Following the release of Django 6.0, we suggest that third-party app authors
drop support for all versions of Django prior to 5.2. At that time, you should
be able to run your package’s tests using python -Wd
so that deprecation
warnings appear. After making the deprecation warning fixes, your app should be
compatible with Django 6.0.
What’s new in Django 6.0¶
Content Security Policy support¶
Built-in support for the Content Security Policy (CSP) standard is now available, making it easier to protect web applications against content injection attacks such as cross-site scripting (XSS). CSP allows declaring trusted sources of content by giving browsers strict rules about which scripts, styles, images, or other resources can be loaded.
CSP policies can now be enforced or monitored directly using built-in tools:
headers are added via the
ContentSecurityPolicyMiddleware
, nonces are
supported through the csp()
context
processor, and policies are configured using the SECURE_CSP
and
SECURE_CSP_REPORT_ONLY
settings.
These settings accept Python dictionaries and support Django-provided constants for clarity and safety. For example:
from django.utils.csp import CSP
SECURE_CSP = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, CSP.NONCE],
"img-src": [CSP.SELF, "https:"],
}
The resulting Content-Security-Policy
header would be set to:
default-src 'self'; script-src 'self' 'nonce-SECRET'; img-src 'self' https:
To get started, follow the CSP how-to guide. For in-depth guidance, see the CSP security overview and the reference docs.
Minor features¶
django.contrib.admin
¶
The Font Awesome Free icon set (version 6.7.2) is now used for the admin interface icons.
django.contrib.admindocs
¶
The new
AdminSite.password_change_form
attribute allows customizing the form used in the admin site password change view.
django.contrib.auth
¶
The default iteration count for the PBKDF2 password hasher is increased from 1,000,000 to 1,200,000.
django.contrib.contenttypes
¶
…
django.contrib.gis
¶
The new
GEOSGeometry.hasm
property checks whether the geometry has the M dimension.The new
Rotate
database function rotates a geometry by a specified angle around the origin or a specified point.The new
BaseGeometryWidget.base_layer
attribute allows specifying a JavaScript map base layer, enabling customization of map tile providers.coveredby
andisvalid
lookups,Collect
aggregation, andGeoHash
andIsValid
database functions are now supported on MariaDB 12.0.1+.
django.contrib.messages
¶
…
django.contrib.postgres
¶
Model fields, indexes, and constraints from
django.contrib.postgres
now include system checks to verify thatdjango.contrib.postgres
is an installed app.
django.contrib.redirects
¶
…
django.contrib.sessions
¶
…
django.contrib.sitemaps
¶
…
django.contrib.sites
¶
…
django.contrib.staticfiles
¶
ManifestStaticFilesStorage
now ensures consistent path ordering in manifest files, making them more reproducible and reducing unnecessary diffs.
Cache¶
…
CSRF¶
…
Decorators¶
…
Email¶
…
Error Reporting¶
…
File Storage¶
…
File Uploads¶
…
Forms¶
…
Generic Views¶
…
Internationalization¶
…
Logging¶
…
Management Commands¶
The
startproject
andstartapp
commands now create the custom target directory if it doesn’t exist.
Migrations¶
Squashed migrations can now themselves be squashed before being transitioned to normal migrations.
Migrations now support serialization of
zoneinfo.ZoneInfo
instances.Serialization of deconstructible objects now supports keyword arguments with names that are not valid Python identifiers.
Models¶
Constraints now implement a
check()
method that is already registered with the check framework.The new
order_by
argument forAggregate
allows specifying the ordering of the elements in the result.The new
Aggregate.allow_order_by
class attribute determines whether the aggregate function allows passing anorder_by
keyword argument.The new
StringAgg
aggregate returns the input values concatenated into a string, separated by thedelimiter
string. This aggregate was previously supported only for PostgreSQL.The
save()
method now raises a specializedModel.NotUpdated
exception, when a forced update results in no affected rows, instead of a genericdjango.db.DatabaseError
.QuerySet.raw()
now supports models with aCompositePrimaryKey
.JSONField
now supports negative array indexing on SQLite.The new
AnyValue
aggregate returns an arbitrary value from the non-null input values. This is supported on SQLite, MySQL, Oracle, and PostgreSQL 16+.
Pagination¶
The new
AsyncPaginator
andAsyncPage
provide async implementations ofPaginator
andPage
respectively.
Requests and Responses¶
…
Security¶
…
Serialization¶
…
Signals¶
…
Templates¶
The new variable
forloop.length
is now available within afor
loop.The
querystring
template tag now consistently prefixes the returned query string with a?
, ensuring reliable link generation behavior.The
querystring
template tag now accepts multiple positional arguments, which must be mappings, such asQueryDict
ordict
.
Tests¶
…
URLs¶
…
Utilities¶
…
Validators¶
…
Backwards incompatible changes in 6.0¶
Database backend API¶
This section describes changes that may be needed in third-party database backends.
BaseDatabaseCreation.create_test_db(serialize)
is deprecated. Useserialize_db_to_string()
instead.BaseDatabaseSchemaEditor
and PostgreSQL backends no longer useCASCADE
when dropping a column.
Dropped support for MariaDB 10.5¶
Upstream support for MariaDB 10.5 ends in June 2025. Django 6.0 supports MariaDB 10.6 and higher.
Dropped support for Python < 3.12¶
Because Python 3.12 is now the minimum supported version for Django, any optional dependencies must also meet that requirement. The following versions of each library are the first to add or confirm compatibility with Python 3.12:
aiosmtpd
1.4.5argon2-cffi
23.1.0bcrypt
4.1.1geoip2
4.8.0Pillow
10.1.0mysqlclient
2.2.1numpy
1.26.0PyYAML
6.0.2psycopg
3.1.12psycopg2
2.9.9redis-py
5.1.0selenium
4.23.0sqlparse
0.5.0tblib
3.0.0
Miscellaneous¶
The JSON serializer now writes a newline at the end of the output, even without the
indent
option set.The undocumented
django.utils.http.parse_header_parameters()
function is refactored to use Python’semail.message.Message
for parsing. Input headers exceeding 10000 characters will now raiseValueError
.Widgets from
django.contrib.gis.forms.widgets
now render without inline JavaScript in templates. If you have customized any geometry widgets or their templates, you may need to update them to match the new layout.Message levels
messages.DEBUG
andmessages.INFO
now have distinct icons and CSS styling in the admin. Previously, these used the same icon and styling as themessages.SUCCESS
level. SinceModelAdmin.message_user()
uses themessages.INFO
level by default, set the level tomessages.SUCCESS
to retain the previous icon and styling.
Features deprecated in 6.0¶
Miscellaneous¶
BaseDatabaseCreation.create_test_db(serialize)
is deprecated. Useserialize_db_to_string()
instead.The PostgreSQL
StringAgg
class is deprecated in favor of the generally availableStringAgg
class.The PostgreSQL
OrderableAggMixin
is deprecated in favor of theorder_by
attribute now available on theAggregate
class.The default protocol in
urlize
andurlizetrunc
will change from HTTP to HTTPS in Django 7.0. Set the transitional settingURLIZE_ASSUME_HTTPS
toTrue
to opt into assuming HTTPS during the Django 6.x release cycle.URLIZE_ASSUME_HTTPS
transitional setting is deprecated.Setting
ADMINS
orMANAGERS
to a list of (name, address) tuples is deprecated. Set to a list of email address strings instead. Django never used the name portion. To include a name, format the address string as'"Name" <address>'
or use Python’semail.utils.formataddr()
.Support for the
orphans
argument being larger than or equal to theper_page
argument ofdjango.core.paginator.Paginator
anddjango.core.paginator.AsyncPaginator
is deprecated.Using a percent sign in a column alias or annotation is deprecated.
Features removed in 6.0¶
These features have reached the end of their deprecation cycle and are removed in Django 6.0.
See Features deprecated in 5.0 for details on these changes, including how to remove usage of these features.
Support for passing positional arguments to
BaseConstraint
is removed.The
DjangoDivFormRenderer
andJinja2DivFormRenderer
transitional form renderers are removed.BaseDatabaseOperations.field_cast_sql()
is removed.request
is required in the signature ofModelAdmin.lookup_allowed()
subclasses.Support for calling
format_html()
without passing args or kwargs is removed.The default scheme for
forms.URLField
changed from"http"
to"https"
.The
FORMS_URLFIELD_ASSUME_HTTPS
transitional setting is removed.The
django.db.models.sql.datastructures.Join
no longer fallback toget_joining_columns()
.The
get_joining_columns()
method ofForeignObject
andForeignObjectRel
is removed.The
ForeignObject.get_reverse_joining_columns()
method is removed.Support for
cx_Oracle
is removed.The
ChoicesMeta
alias todjango.db.models.enums.ChoicesType
is removed.The
Prefetch.get_current_queryset()
method is removed.The
get_prefetch_queryset()
method of related managers and descriptors is removed.get_prefetcher()
andprefetch_related_objects()
no longer fallback toget_prefetch_queryset()
.
See Features deprecated in 5.1 for details on these changes, including how to remove usage of these features.
django.urls.register_converter()
no longer allows overriding existing converters.The
ModelAdmin.log_deletion()
andLogEntryManager.log_action()
methods are removed.The undocumented
django.utils.itercompat.is_iterable()
function and thedjango.utils.itercompat
module is removed.The
django.contrib.gis.geoip2.GeoIP2.coords()
method is removed.The
django.contrib.gis.geoip2.GeoIP2.open()
method is removed.Support for passing positional arguments to
Model.save()
andModel.asave()
is removed.The setter for
django.contrib.gis.gdal.OGRGeometry.coord_dim
is removed.The
check
keyword argument ofCheckConstraint
is removed.The
get_cache_name()
method ofFieldCacheMixin
is removed.The
OS_OPEN_FLAGS
attribute ofFileSystemStorage
is removed.