Expected August 2024
Welcome to Django 5.1!
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.0 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.1 supports Python 3.10, 3.11, and 3.12. We highly recommend and only officially support the latest release of each series.
django.contrib.admin
¶ModelAdmin.list_display
now supports using __
lookups to list
fields from related models.django.contrib.auth
¶BaseUserCreationForm
and
AdminPasswordChangeForm
now support
disabling password-based authentication by setting an unusable password on
form save. This is now available in the admin when visiting the user creation
and password change pages.login_required()
,
permission_required()
, and
user_passes_test()
decorators now
support wrapping asynchronous view functions.django.contrib.gis
¶BoundingCircle
is now
supported on SpatiaLite 5.1+.Collect
is now supported on MySQL
8.0.24+.GeoIP2
now allows querying using
ipaddress.IPv4Address
or ipaddress.IPv6Address
objects.GeoIP2.country()
now exposes the continent_code
,
continent_name
, and is_in_european_union
values.GeoIP2.city()
now exposes the accuracy_radius
and region_name
values. In addition the dma_code
and region
values are now exposed as
metro_code
and region_code
, but the previous keys are also retained
for backward compatibility.Area
now supports the ha
unit.OGRGeometry.is_3d
attribute allows checking if a geometry
has a Z
coordinate dimension.OGRGeometry.set_3d()
method allows addition and removal of the
Z
coordinate dimension.OGRGeometry
,
Point
,
LineString
,
Polygon
, and
GeometryCollection
and its subclasses now
support measured geometries via the new OGRGeometry.is_measured
and
m
properties, and the OGRGeometry.set_measured()
method.OGRGeometry.centroid
is now available on all supported geometry
types.FromWKB()
and
FromWKT()
functions
now support the optional srid
argument (except for Oracle where it is
ignored).django.contrib.postgres
¶BTreeIndex
now supports the
deduplicate_items
parameter.django.contrib.sessions
¶django.contrib.sessions.backends.cached_db.SessionStore
now handles
exceptions when storing session information in the cache, logging proper
error messages with their traceback via the newly added
sessions logger.django.contrib.sessions.backends.base.SessionBase
and all built-in
session engines now provide async API. The new asynchronous methods all have
a
prefixed names, e.g. aget()
, akeys()
, or acycle_key()
."init_command"
option is now supported in OPTIONS
on SQLite
to allow specifying pragma options to set upon
connection."pool"
option is now supported in OPTIONS
on PostgreSQL to
allow using connection pools.aria-describedby
HTML attribute.makemigrations
command now displays meaningful symbols for each
operation to highlight operation categories
.Operation.category
attribute allows specifying an
operation category
used by the
makemigrations
to display a meaningful symbol for the operation.QuerySet.explain()
now supports the generic_plan
option on
PostgreSQL 16+.RowRange
now accepts positive integers
for the start
argument and negative integers for the end
argument.exclusion
argument of
RowRange
and
ValueRange
allows excluding rows,
groups, and ties from the window frames.QuerySet.order_by()
now supports ordering by annotation transforms
such as JSONObject
keys and ArrayAgg
indices.F()
and OuterRef()
expressions that output
CharField
, EmailField
,
SlugField
, URLField
,
TextField
, or
ArrayField
can now be sliced.from_queryset
argument of Model.refresh_from_db()
and
Model.arefresh_from_db()
allows customizing the queryset used to
reload a model’s value. This can be used to lock the row before reloading or
to select related objects."transaction_mode"
option is now supported in OPTIONS
on SQLite to allow specifying the Transactions behavior.Parser
object that will later
be made available on the Template
instance. Such data may be used, for
example, by the template loader, or other template clients.{% query_string %}
template tag allows
changing a QueryDict
instance for use in links, for
example, to generate a link to the next page while keeping any filtering
options in place.assertContains()
,
assertNotContains()
, and
assertInHTML()
assertions now add haystacks
to assertion error messages.
The RequestFactory
,
AsyncRequestFactory
, Client
, and
AsyncClient
classes now support the query_params
parameter, which accepts a dictionary of query string keys and values. This
allows setting query strings on any HTTP methods more easily.
self.client.post("/items/1", query_params={"action": "delete"})
await self.async_client.post("/items/1", query_params={"action": "delete"})
The new SimpleTestCase.assertNotInHTML()
assertion allows testing that
an HTML fragment is not contained in the given HTML haystack.
In order to enforce test isolation, database connections inside threads are
no longer allowed in SimpleTestCase
.
This section describes changes that may be needed in third-party database backends.
django.contrib.gis
¶GeoIP2
no longer opens both city and
country databases when a directory path is provided, preferring the city
database, if it is available. The country database is a subset of the city
database and both are not typically needed. If you require use of the country
database when in the same directory as the city database, explicitly pass the
country database path to the constructor.Upstream support for MariaDB 10.4 ends in June 2024. Django 5.1 supports MariaDB 10.5 and higher.
Upstream support for PostgreSQL 12 ends in November 2024. Django 5.1 supports PostgreSQL 13 and higher.
<nav>
tag instead of a <div>
.<footer>
tag instead of a <div>
, and also moved below the
<div id="main">
element.SimpleTestCase.assertURLEqual()
and
assertInHTML()
now add ": "
to the
msg_prefix
. This is consistent with the behavior of other assertions.django.utils.text.Truncator
used by truncatechars_html
and
truncatewords_html
template filters now uses
html.parser.HTMLParser
subclasses. This results in a more robust
and faster operation, but there may be small differences in the output.django.urls.converters.get_converter()
function is
removed.ModelAdmin.log_deletion()
and LogEntryManager.log_action()
methods are deprecated. Subclasses should implement
ModelAdmin.log_deletions()
and LogEntryManager.log_actions()
instead.django.utils.itercompat.is_iterable()
function and the
django.utils.itercompat
module are deprecated. Use
isinstance(..., collections.abc.Iterable)
instead.django.contrib.gis.geoip2.GeoIP2.coords()
method is deprecated. Use
django.contrib.gis.geoip2.GeoIP2.lon_lat()
instead.django.contrib.gis.geoip2.GeoIP2.open()
method is deprecated. Use the
GeoIP2
constructor instead.Model.save()
and Model.asave()
is deprecated in favor of keyword-only arguments.django.contrib.gis.gdal.OGRGeometry.coord_dim
is deprecated. Use
set_3d()
instead.django.urls.register_converter()
is
deprecated.check
keyword argument of CheckConstraint
is deprecated in favor
of condition
.These features have reached the end of their deprecation cycle and are removed in Django 5.1.
See Features deprecated in 4.2 for details on these changes, including how to remove usage of these features.
BaseUserManager.make_random_password()
method is removed.Meta.index_together
option is removed.length_is
template filter is removed.django.contrib.auth.hashers.SHA1PasswordHasher
,
django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher
, and
django.contrib.auth.hashers.UnsaltedMD5PasswordHasher
are removed.django.contrib.postgres.fields.CICharField
,
django.contrib.postgres.fields.CIEmailField
, and
django.contrib.postgres.fields.CITextField
are removed, except for
support in historical migrations.django.contrib.postgres.fields.CIText
mixin is removed.map_width
and map_height
attributes of BaseGeometryWidget
are
removed.SimpleTestCase.assertFormsetError()
method is removed.TransactionTestCase.assertQuerysetEqual()
method is removed.JSONField
and
associated lookups and expressions is removed.Signer
and
TimestampSigner
is removed.DEFAULT_FILE_STORAGE
and STATICFILES_STORAGE
settings is removed.django.core.files.storage.get_storage_class()
function is removed.Mar 18, 2024