What Is New in Django 3.2
Django 3.2 introduces a significant Long-Term Support (LTS) release, bringing a mix of new features, performance enhancements, and the usual set of deprecations. The key updates are summarized below.
| Category | Key Changes |
|---|---|
| New Features | Customizing automatic AppConfig discovery, Functional indexes, New async support |
| Improvements | Faster model field validation, JSONField for all supported DBs, New admin sidebar |
| Database | Functional indexes, New collations, Support for spatialite 5 |
| Admin | Responsive sidebar, Improved navigation |
| Deprecations | Dropped support for PostgreSQL 9.6, MySQL 5.7, Oracle 12.2 |
How does Django 3.2 improve database performance?
Functional indexes are the headline database feature. They let you create indexes on expressions, not just field values, which is a game-changer for complex queries.
You can now define them directly in your model's Meta class. This is much cleaner than writing raw SQL migrations for the same result. For example, indexing the lowercased version of a field for case-insensitive lookups is straightforward.
from django.db import models
from django.db.models import Index
class Book(models.Model):
title = models.CharField(max_length=100)
class Meta:
indexes = [
Index(Lower('title'), name='title_lower_idx'),
]
In practice, this matters because it pushes complex data filtering logic down to the database level, which is almost always faster than doing it in Python.
What new async features were added?
The async ORM support expanded significantly. While not yet complete, 3.2 added async versions of the ORM's get() and delete() operations.
This builds on the async views and middleware from 3.1. You can now do await Model.objects.aget(id=1) and await Model.objects.adelete().
This is a crucial step towards a fully asynchronous ORM. It allows for more efficient handling of I/O-bound workloads within a single async view, reducing the need to jump back to a sync thread.
How is the admin interface better?
The admin got a responsive sidebar navigation menu, replacing the old top-bar design on larger screens. This is a major UX improvement for apps with many models.
The sidebar is collapsible, making better use of screen real estate. It also groups apps and models more intuitively. This change is purely visual and doesn't break existing custom templates.
For developers, it means less need to immediately reach for third-party admin themes for basic usability. The default experience is now much more modern.
What about configuring apps differently?
Customizing AppConfig discovery is a subtle but powerful change for larger projects. You can now control how Django automatically finds apps without needing a verbose apps.py for every app.
By setting default_app_config in your __init__.py, you can point to a custom AppConfig class. This simplifies configuration for apps that need non-default setup but want to maintain conventional app naming.
# myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
This cleans up project structure by keeping explicit configuration choices in one obvious place.
Were there any important deprecations?
Yes, support for several older database versions was dropped. This is standard for an LTS release to define a modern supported platform baseline for the next few years.
PostgreSQL 9.6, MySQL 5.7, and Oracle 12.2 and earlier are no longer supported. You'll need to upgrade your database to use Django 3.2. SQLite and MariaDB version support remained the same.
This matters because it allows the core team to use newer database features and simplifies the codebase. Always check your DB version against the release notes before upgrading.
FAQ
Is Django 3.2 a Long-Term Support (LTS) release?
Yes, Django 3.2 is an LTS release. This means it will receive security updates and data loss fixes for at least three years, making it the preferred version for production deployments that require stability.
Can I use JSONField with MySQL and Oracle now?
Absolutely. Django 3.2 finally brings the JSONField to all supported database backends (PostgreSQL, MySQL, Oracle, SQLite). You no longer need to rely on third-party packages for consistent JSON field support across different databases.
What is the deal with the new "test --parallel" default?
The test --parallel flag now defaults to using the number of CPU cores available. This can significantly speed up your test suite by running tests concurrently. If it causes issues, you can override it with --parallel=1.
Are there any changes to the way default primary keys work?
Yes. New models that don't have an explicit primary key now get a BigAutoField instead of an AutoField. This prevents integer overflow for tables with over 2 billion rows. Existing projects are unaffected unless you create new models.
I use GIS. What's new for me?
Django 3.2 adds support for SpatiaLite 5.0+. If you're using the SQLite spatial backend, you'll need to ensure your environment has the updated spatial library to take advantage of new GIS features and fixes.