Django 3.0 Released: ASGI Support Arrives
Django 3.0 landed on December 2, 2019. The headline: native ASGI support. Python 2 is finally gone. The async future begins.
Breaking Changes
Python 2 Is Gone
Django 3.0 requires Python 3.6+. Python 3.8 recommended.
# Check your version
python --version
# Update if needed
pyenv install 3.8.0
pyenv local 3.8.0
If you have Python 2 code, you can’t skip to Django 3.0. Upgrade to Python 3 first, then Django.
MySQL 5.6+ Required
Older MySQL versions are no longer supported.
Other Deprecations Removed
Things deprecated in 2.0/2.1 are now gone:
django.utils.encoding.python_2_unicode_compatibledjango.utils.six- Various other Python 2 compatibility shims
ASGI Support
The main event. Django now speaks ASGI natively.
Creating the ASGI Application
# myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = get_asgi_application()
Running with ASGI Servers
# Uvicorn
pip install uvicorn
uvicorn myproject.asgi:application
# Daphne
pip install daphne
daphne myproject.asgi:application
# Hypercorn
pip install hypercorn
hypercorn myproject.asgi:application
What Works in ASGI Mode
Everything that worked in WSGI still works. ASGI is backward compatible.
What’s new:
- Async middleware support
- Foundation for future async views
- WebSocket support (via Channels)
What Doesn’t Work Yet
- Async views (coming in 3.1)
- Async ORM queries (future releases)
- Async template rendering (future releases)
Django 3.0 is the foundation, not the finish line.
New Features
MariaDB Support
Official MariaDB backend:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydb',
'OPTIONS': {
'read_default_file': '/path/to/my.cnf',
},
}
}
Exclusion Constraints (PostgreSQL)
from django.contrib.postgres.constraints import ExclusionConstraint
from django.contrib.postgres.fields import DateTimeRangeField, RangeOperators
class Reservation(models.Model):
room = models.ForeignKey(Room, on_delete=models.CASCADE)
timespan = DateTimeRangeField()
class Meta:
constraints = [
ExclusionConstraint(
name='no_overlapping_reservations',
expressions=[
('room', RangeOperators.EQUAL),
('timespan', RangeOperators.OVERLAPS),
],
),
]
Prevent overlapping time ranges at the database level.
Filter Expressions
New database functions for filtering:
from django.db.models import Value
from django.db.models.functions import Reverse, Length
# Reverse strings
Article.objects.annotate(reversed_title=Reverse('title'))
# More function expressions available
Enum Improvements
Better support for Python Enums:
from enum import Enum
class Status(Enum):
DRAFT = 'draft'
PUBLISHED = 'published'
ARCHIVED = 'archived'
class Article(models.Model):
status = models.CharField(
max_length=20,
choices=[(s.value, s.name) for s in Status],
default=Status.DRAFT.value,
)
Security Updates
Password Hashing
PBKDF2 iterations increased again. Existing passwords auto-upgrade on login.
SECURE_REFERRER_POLICY
New setting for the Referrer-Policy header:
SECURE_REFERRER_POLICY = 'same-origin'
Upgrade Path
From Django 2.2 LTS
Smoothest path:
- Ensure you’re on Python 3.6+
- Run with deprecation warnings:
python -Wd manage.py test - Fix deprecation warnings
- Upgrade Django
- Run tests
From Django 2.0/2.1
Same process, but more deprecations to address.
From Django 1.11 LTS
Larger jump:
- Upgrade to Python 3.6+
- Upgrade to Django 2.2 LTS first
- Fix all deprecations
- Then upgrade to 3.0
Using Channels with Django 3.0
Django Channels works with ASGI:
# asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
import myapp.routing
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = ProtocolTypeRouter({
"http": get_asgi_application(),
"websocket": AuthMiddlewareStack(
URLRouter(
myapp.routing.websocket_urlpatterns
)
),
})
Should You Upgrade?
Upgrade if:
- You’re starting a new project
- You want ASGI/async foundation
- You’re on Django 2.0/2.1 (no longer supported)
Wait if:
- You’re on Django 2.2 LTS (supported until April 2022)
- Critical dependencies aren’t 3.0 compatible
- You need stability over features
The Async Roadmap
Django’s async journey:
- 3.0: ASGI support, async middleware
- 3.1: Async views, async handlers
- 3.2 LTS: Consolidation
- Future: Async ORM
The goal is full async capability without breaking sync code.
Final Thoughts
Django 3.0 is a milestone—the first step into async Django. The foundation is laid.
For most projects, the upgrade is straightforward. Python 3 requirement finally cleans up years of compatibility shims.
Welcome to async Django. The future is being built.
The async journey begins.