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:
DATABASES = {
"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 standardfunctools
version. Model.save()
andModel.delete()
no longer accept positional arguments, only keyword arguments.
See the release notes for a few other minor backward incompatible changes.
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 ofdjango.utils.functional.lazy()
is deprecated. Usefunctools.partial()
instead for naming lazy objects. - Using more than one model in
ModelAdmin.ordering
orModelAdmin.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 byWidget.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.
Conclusion
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.