Exciting news for Django developers! The next major release, Django 5.1, is currently under active development and slated for release in August 2024. This article covers the key new features and improvements you can look forward to, as well as tips for smoothly upgrading your projects to take advantage of everything Django 5.1 has to offer.

What’s new in Django 5.1

{% query_string %} template tag

Modifying URL query parameters in templates has gotten much easier thanks to the new {% query_string %} tag. No more manually looping through request.GET – simply use {% query_string page=page.next_page_number %} to generate a new URL while maintaining existing query parameters. This will be a huge time saver, especially for common tasks like pagination links.

# Current way
a href="?{% for key, values in request.GET.iterlists %}
  {% if key != "page" %}
    {% for value in values %}
      {{ key }}={{ value }}&
    {% endfor %}
  {% endif %}
{% endfor %}page={{ page.next_page_number }}">Next page

Will become:

a href="{% query_string page=page.next_page_number %}">Next page

PostgreSQL connection pools

If you use PostgreSQL, 5.1 adds built-in support for connection pooling via the ‘pool’ option in your database settings. Connection pools help reduce latency by keeping database connections open. Just set 'pool': True in your db options or customize the pool settings. This will give your app a nice performance boost! Short example:

    "default": {
        "ENGINE": "django.db.backends.postgresql",
        # ...
        "OPTIONS": {
            "pool": {
                "min_size": 2,
                "max_size": 4,
                "timeout": 10,

LoginRequiredMiddleware for authentication

The new LoginRequiredMiddleware makes it easy to require authentication for all or most pages, without having to decorate each view. Simply add it to MIDDLEWARE and all requests will require login, unless the view is decorated with login_not_required(). This provides a convenient way to enforce authentication app-wide.

Simplified password management

The auth contrib app includes several improvements around password management. The default PBKDF2 and Scrypt parameters have been tuned to the latest security recommendations. Password change/reset forms make it easy to disable password auth entirely. And the admin now includes a handy “reset password” button. These enhancements make dealing with passwords simpler and more secure.

GeoDjango upgrades

As always, GeoDjango continues to add support for the latest geospatial database features. 5.1 adds support for new functions and options in PostGIS, SpatiaLite, MySQL, and Oracle. There are also new GeoIP2 features for working with IP addresses. And many geometry operations and properties have been enhanced, like 3D/4D support, better centroid handling, and more.

Management command

The makemigrations command will now use intuitive symbols to highlight the different types of migration operations, making long migration lists easier to quickly scan. And the createsuperuser command includes a --email option to specify the superuser email, saving you a prompt.

Template engine extensibility

Template engine implementations can now define a check() method that registers checks for use with the system check framework.

This enables template-specific checks, such as invalid filter names or tag libraries that won’t load. Also, custom template tags can now attach additional data to the parser and make it available on the final template, in case your tags need a way to pass information to later template processing stages.

Testing improvements

The RequestFactory and test Client now support a query_params argument so you can more easily specify query strings for test requests.

In the template assertContains/assertNotContains assertions, the error messages will now display the full contents that didn’t match, making it easier to see why an assertion failed. And SimpleTestCase disallows database queries during tests to better enforce test isolation.

Backward incompatible changes

As with any major release, Django 5.1 contains some backwards incompatible changes to be aware of:

  • Several legacy database backends and versions are no longer supported, including MySQL 5.6, Oracle 12.1, and SQLite 3.9.0. Be sure to upgrade to a fully supported database version.
  • The undocumented django.urls.resolvers.get_resolver() function is removed.
  • Overriding an already registered URL converter is no longer allowed.
  • The private django.utils.functional.cached_property is replaced by the standard functools version.
  • Model.save() and Model.delete() no longer accept positional arguments, only keyword arguments.

See the release notes for a few other minor backward incompatible changes.

Django book

Deprecations galore

Django 5.1 continues to trim obsolete functionality slated for future removal:

  • The makemigrations --exit option is deprecated as it doesn’t work as expected.
  • The providing_args argument for custom template tags is deprecated as it’s a frequent source of confusion.
  • The name argument of django.utils.functional.lazy() is deprecated. Use functools.partial() instead for naming lazy objects.
  • Using more than one model in ModelAdmin.ordering or ModelAdmin.readonly_fields will raise an error in Django 5.2.
  • The HttpRequest.is_ajax() method is deprecated as it relies on a jQuery-specific way of signifying AJAX calls, while current usage tends to use the JavaScript Fetch API.

See the deprecation timeline for the full list of deprecations and when they are scheduled for removal.

Removed features

This release completes the deprecation cycle for some legacy features:

  • The SessionAuthenticationMiddleware is removed as it provided no functionality since session authentication is unconditionally enabled in Django 1.10.
  • The django.utils.encoding.python_2_unicode_compatible() decorator is removed.
  • The django.utils.decorators.ContextDecorator class is removed.
  • The django.utils.decorators.available_attrs() function is removed.
  • The Widget.render() method is removed, replaced by Widget.render().

Tips for upgrading to Django 5.1

To ensure a smooth upgrade, it’s recommended to incrementally adopt each Django release, rather than skipping major versions. Plan to budget time for resolving deprecation warnings and adjusting to backwards incompatible changes.

Before upgrading, make sure to:

  • Resolve deprecation warnings in your current version before attempting an upgrade. Warnings indicate code that needs updating.
  • Read the release notes, particularly any backwards incompatible changes and features removed, to see what will require code changes in your project.
  • Upgrade any third party packages to versions compatible with Django 5.1.
  • Check their documentation to determine which versions support the new Django release.

Once your code is ready, upgrading involves:

  • Updating the Django version, typically by running pip install -U Django.
  • Running your test suite and fixing any failures.
  • Deploying the upgraded code into production.
  • Clearing your cache if you are using Django’s caching functionality. Caches can contain data structures that aren’t compatible between versions.

By planning ahead and following best practices, you can keep your Django projects current with the latest releases, enabling you to take advantage of new features and stay secure.


The Django 5.1 release packs in a bunch of useful improvements while maintaining the framework’s reputation for stability and backwards compatibility. Highlights include easier query parameter handling in templates, PostgreSQL connection pooling, geospatial enhancements, and more.

Now is a great time to begin prepping your projects to hit the ground running when Django 5.1 lands in August. Resolve deprecation warnings, ensure third party packages are upgraded, and adjust any code that will be impacted by backwards incompatible changes. A smooth upgrade process is well worth the effort to leverage the latest and greatest Django has to offer.

Stay tuned for the official Django 5.1 release in a few short months.

Categorized in:

MLOps, Models deployment, Programming,

Last Update: 01/07/2024