Django 3.2 LTS: Why You Should Upgrade
Django 3.2 LTS is here. With support until April 2024, it’s the stable foundation for the next three years. Here’s what’s new and why you should upgrade.
LTS Explained
| Version | Release | End Support |
|---|---|---|
| Django 2.2 LTS | Apr 2019 | Apr 2022 |
| Django 3.2 LTS | Apr 2021 | Apr 2024 |
| Django 4.2 LTS | Apr 2023 | Apr 2026 |
LTS releases get security updates for 3 years. Non-LTS releases only get 16 months.
New Features
Functional Indexes
Create indexes on expressions:
from django.db import models
from django.db.models.functions import Lower
class Article(models.Model):
title = models.CharField(max_length=200)
class Meta:
indexes = [
models.Index(Lower('title'), name='lower_title_idx'),
]
Useful for case-insensitive queries:
# This query can now use the index
Article.objects.filter(title__iexact='django guide')
Covering Indexes (PostgreSQL)
Include additional columns in indexes:
class Article(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
created_at = models.DateTimeField()
class Meta:
indexes = [
models.Index(
fields=['author'],
include=['title', 'created_at'],
name='author_covering_idx',
),
]
The index includes title and created_at, enabling index-only scans:
# May avoid table access entirely
Article.objects.filter(author=user).values('title', 'created_at')
JSONField for All Databases
JSONField now works on all databases, not just PostgreSQL:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
preferences = models.JSONField(default=dict)
# Usage
profile.preferences = {
'theme': 'dark',
'notifications': True,
'sidebar_collapsed': False
}
profile.save()
# Query
Profile.objects.filter(preferences__theme='dark')
SQLite, MySQL, and MariaDB now supported.
AppConfig.default_auto_field
Control default primary key type:
# settings.py
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Or per-app:
# myapp/apps.py
class MyAppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'myapp'
New projects default to BigAutoField. Existing projects should migrate carefully.
Admin Site Improvements
Native dark mode support:
# Django detects system preference
# Or override in templates
Other admin improvements:
- Better filter handling
- Improved mobile responsiveness
- Enhanced sidebar
Collation Support
Database collation on CharField:
class Name(models.Model):
name = models.CharField(
max_length=100,
db_collation='en_US.utf8'
)
Useful for locale-specific sorting.
Simplified URL Patterns
Optional capturing groups:
# Before
path('articles/', views.list),
path('articles/<int:year>/', views.list),
# After (Django 3.2+)
re_path(r'^articles/(?:(?P<year>\d{4})/)?$', views.list),
Performance Improvements
Optimized ORM
Query generation is faster:
- Reduced memory allocation
- Better query caching
- Improved prefetching
Cached Template Loader Default
In production, templates are cached by default:
# DEBUG = False automatically enables caching
Deprecations
url() is Gone
Use path() or re_path():
# Old (removed in Django 4.0)
from django.conf.urls import url
url(r'^articles/$', views.list)
# New
from django.urls import path, re_path
path('articles/', views.list)
re_path(r'^articles/(?P<slug>[\w-]+)/$', views.detail)
Upgrade Guide
Step 1: Check Compatibility
python -Wd manage.py test
Review deprecation warnings.
Step 2: Update Dependencies
pip install Django==3.2
pip install --upgrade psycopg2 celery djangorestframework
Check all packages support Django 3.2.
Step 3: Run Migrations
python manage.py migrate
Step 4: Handle Auto Field Warnings
You’ll see warnings about DEFAULT_AUTO_FIELD:
# Add to settings.py to maintain current behavior
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# Or for new projects, use BigAutoField
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
Step 5: Test Thoroughly
python manage.py test
Step 6: Update url() to path()
# Search for url( and replace with path( or re_path(
Should You Upgrade?
From Django 2.2 LTS
Yes. 2.2 support ends April 2022:
- 3 years of security updates on 3.2
- Async views available
- JSONField improvements
From Django 3.0/3.1
Yes. Non-LTS releases have shorter support:
- 3.2 LTS gives you stability
- Continue to 4.0 when ready
From Older Versions
Upgrade path:
Django 1.11 → 2.2 → 3.2
Don’t skip LTS versions.
Final Thoughts
Django 3.2 LTS is the stable choice for production. Functional indexes, universal JSONField, and three years of support make it the foundation for serious projects.
Upgrade now. Your future self will thank you.
LTS: Long-Term Stability.