What Is New in Django 3.1
Django 3.1 introduces significant features focused on asynchronous views and middleware, JSONField for all supported databases, and a host of smaller improvements. This release makes async a first-class citizen in the framework.
| Category | Key Changes |
|---|---|
| New Features | Asynchronous views and middleware, JSONField for all databases, Customizing navigation sidebar in admin |
| Improvements | New template tags, Model field and form field enhancements, Testing framework additions |
| Deprecations | Deprecated django.utils.translation.ugettext, ugettext_lazy, ugettext_noop, and related functions |
How does async support work in Django 3.1?
Django 3.1 adds support for asynchronous views, middleware, and tests. You can now define a view using async def and Django will handle it in an asynchronous context. This is a foundational step for full async support in future releases.
In practice, this means you can use async/await within your view logic to call other async functions. The middleware stack can also include async-capable middleware, allowing for async processing of requests and responses.
Example Async View
async def my_view(request):
await asyncio.sleep(0.5)
return HttpResponse('Hello, async world!')
What's the deal with the new JSONField?
Previous versions of Django included a JSONField only for PostgreSQL. Django 3.1 extends this functionality to all supported database backends (SQLite, MySQL, Oracle, PostgreSQL). This provides a consistent API for storing JSON data regardless of your database.
This matters because it simplifies your model definitions. You no longer need to use a third-party package or write different field logic for development (often SQLite) and production (often PostgreSQL). The new field uses the database's native JSON support where available.
Using the Universal JSONField
from django.db import models
class Product(models.Model):
details = models.JSONField()
# Works on SQLite, MySQL, PostgreSQL, and Oracle
What admin interface improvements were made?
The admin interface got a useful customization option for the navigation sidebar. You can now control which apps and models are displayed in the sidebar by setting the AdminSite.enable_nav_sidebar attribute. This allows for a cleaner admin experience for users with specific permissions.
Additionally, the admin now uses a more modern approach for CSS and JavaScript, but maintains full backwards compatibility. The jQuery version was upgraded to 3.5.1.
What template and form enhancements are included?
Several new template tags and filters were added to make frontend work smoother. The dictsort filter can now sort a list of dictionaries by a specified key, which is handy for displaying dynamic data tables.
For forms, the ClearableFileInput widget now includes a template for rendering, making it easier to customize its appearance. The EmailField and URLField now use the type="email" and type="url" HTML input types by default, improving usability on mobile devices.
New Template Filter
<!-- Sort a list of people by last name -->
{{ people|dictsort:"last_name" }}
FAQ
Is my existing code using PostgreSQL's JSONField broken?
No, the old django.contrib.postgres.fields.JSONField remains and is not deprecated. Your existing code will continue to work. The new universal models.JSONField is the recommended field for new projects.
Can I mix async and sync middleware?
Yes, Django's middleware stack is designed to handle a mix of synchronous and asynchronous middleware. It will adapt accordingly, though for best performance, it's ideal to make your middleware async-capable if possible.
What happened to the old translation functions like ugettext?
Functions like ugettext, ugettext_lazy, and ugettext_noop are deprecated. You should replace them with their non-Unicode-prefixed equivalents: gettext, gettext_lazy, and gettext_noop. These modern functions work exactly the same way in Python 3.
Does the async support mean Django is now fully async?
Not yet. While views and middleware can be async, the ORM (database layer) is still synchronous. This initial support lays the groundwork for async ORM operations in future versions of Django.
How do I disable the new admin sidebar?
You can disable the navigation sidebar across your entire admin site by setting admin.site.enable_nav_sidebar = False in your project's urls.py file. You can also control this on a per-user basis with permissions.