- Language: en
- Documentation version: development
Django 4.1 release notes - UNDER DEVELOPMENT¶
Expected August 2022
Welcome to Django 4.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 4.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 4.1 supports Python 3.8, 3.9, and 3.10. We highly recommend and only officially support the latest release of each series.
What’s new in Django 4.1¶
- The admin dark mode CSS variables are now applied in a separate stylesheet and template block.
- ModelAdmin List Filters providing custom
FieldListFiltersubclasses can now control the query string value separator when filtering for multiple values using the
- The admin
history viewis now paginated.
- The default iteration count for the PBKDF2 password hasher is increased from 320,000 to 390,000.
- The new
GEOSGeometry.make_valid()method allows converting invalid geometries to valid ones.
- The new
BitXor()aggregate function returns an
intof the bitwise
XORof all non-null input values.
SpGistIndexnow supports covering indexes on PostgreSQL 14+.
ExclusionConstraintnow supports covering exclusion constraints using SP-GiST indexes on PostgreSQL 14+.
- The new
DecimalRangeFieldallows specifying bounds for list and tuple inputs.
ExclusionConstraintnow allows specifying operator classes with the
ManifestStaticFilesStoragenow replaces paths to CSS source map references with their hashed counterparts.
i18n_patterns()function now supports languages with both scripts and regions.
makemigrations --no-inputnow logs default answers and reasons why migrations cannot be created.
- The new
makemigrations --scriptableoption diverts log output and input prompts to
stderr, writing only paths of generated migration files to
- The new
migrate --pruneoption allows deleting nonexistent migrations from the
order_byargument of the
Windowexpression now accepts string references to fields and transforms.
- The new
CONN_HEALTH_CHECKSsetting allows enabling health checks for persistent database connections in order to reduce the number of failed requests, e.g. after database server restart.
QuerySet.bulk_create()now supports updating fields when a row insertion fails uniqueness constraints. This is supported on MariaDB, MySQL, PostgreSQL, and SQLite 3.24+.
QuerySet.iterator()now supports prefetching related objects as long as the
chunk_sizeargument is provided. In older versions, no prefetching was done.
Requests and Responses¶
json_scripttemplate filter now allows wrapping in a
<script>tag without the HTML
- A nested atomic block marked as durable in
django.test.TestCasenow raises a
RuntimeError, the same as outside of tests.
Backwards incompatible changes in 4.1¶
Database backend API¶
This section describes changes that may be needed in third-party database backends.
BaseDatabaseFeatures.has_case_insensitive_likeis changed from
Falseto reflect the behavior of most databases.
DatabaseIntrospection.get_key_columns()is removed. Use
DatabaseOperations.ignore_conflicts_suffix_sql()method is replaced by
DatabaseOperations.on_conflict_suffix_sql()that accepts the
ignore_conflictsargument of the
DatabaseOperations.insert_statement()method is replaced by
Dropped support for MariaDB 10.2¶
Upstream support for MariaDB 10.2 ends in May 2022. Django 4.1 supports MariaDB 10.3 and higher.
Admin changelist searches spanning multi-valued relationships changes¶
Admin changelist searches using multiple search terms are now applied in a
single call to
filter(), rather than in sequential
For multi-valued relationships, this means that rows from the related model
must match all terms rather than any term. For example, if
is set to
['child__name', 'child__age'], and a user searches for
'Jamal 17', parent rows will be returned only if there is a relationship to
some 17-year-old child named Jamal, rather than also returning parents who
merely have a younger or older child named Jamal in addition to some other
See the Spanning multi-valued relationships topic for more discussion of
this difference. In Django 4.0 and earlier,
get_search_results() followed the
second example query, but this undocumented behavior led to queries with
- Related managers for
GenericRelationare now cached on the
Modelinstance to which they belong.
- The Django test runner now returns a non-zero error code for unexpected
successes from tests marked with
CsrfViewMiddlewareno longer masks the CSRF cookie like it does the CSRF token in the DOM.
request.META['CSRF_COOKIE']for storing the unmasked CSRF secret rather than a masked version. This is an undocumented, private API.
inlinesattributes now default to an empty tuple rather than an empty list to discourage unintended mutation.
type="text/css"attribute is no longer included in
<link>tags for CSS form media.
Features deprecated in 4.1¶
The context for sitemap index templates of a flat list of URLs is deprecated. Custom sitemap index templates should be updated for the adjusted context variables, expecting a list of objects with
CSRF_COOKIE_MASKEDtransitional setting is deprecated.
django.utils.functional.cached_property()is deprecated as it’s unnecessary as of Python 3.6.
django.contrib.postgres.constraints.ExclusionConstraintis deprecated in favor of using
ExclusionConstraint.expressions. To use it, you need to add
After making this change,
makemigrationswill generate a new migration with two operations:
AddConstraint. Since this change has no effect on the database schema, the
SeparateDatabaseAndStateoperation can be used to only update the migration state without running any SQL. Move the generated operations into the
SeparateDatabaseAndState. For example:
class Migration(migrations.Migration): ... operations = [ migrations.SeparateDatabaseAndState( database_operations=, state_operations=[ migrations.RemoveConstraint( ... ), migrations.AddConstraint( ... ), ], ), ]
exc_infoargument of the undocumented
django.utils.log.log_response()function is replaced by
django.contrib.sessions.serializers.PickleSerializeris deprecated due to the risk of remote code execution.
The usage of
QuerySet.iterator()on a queryset that prefetches related objects without providing the
chunk_sizeargument is deprecated. In older versions, no prefetching was done. Providing a value for
chunk_sizesignifies that the additional query per chunk needed to prefetch is desired.
Features removed in 4.1¶
These features have reached the end of their deprecation cycle and are removed in Django 4.1.
See Features deprecated in 3.2 for details on these changes, including how to remove usage of these features.
- Support for assigning objects which don’t support creating deep copies with
copy.deepcopy()to class attributes in
- Support for using a boolean value in
default_app_configapplication configuration variable is removed.
TransactionTestCase.assertQuerysetEqual()no longer calls
repr()on a queryset when compared to string values.
django.core.cache.backends.memcached.MemcachedCachebackend is removed.
- Support for the pre-Django 3.2 format of messages used by