What Is New in Django 5.0
Django 5.0 introduces a set of focused enhancements that streamline database interactions and form handling. The update is packed with features that developers will appreciate for their immediate utility.
| Category | Key Changes |
|---|---|
| New Features | GeneratedField, Database-Computed Defaults, Field Choices groups, Simplified form templates |
| Improvements | Async support for send_mail(), scroll-to-bottom for admin log, Extra context for admin forms |
| Deprecations | BaseCommentAbstractModel, postgresql_psycopg2 database engine, django.contrib.postgres.fields.JSONField |
How does GeneratedField change database modeling?
The GeneratedField allows you to define database-generated columns directly in your Django models. This means the database itself computes the field's value from other fields in the same row.
In practice, this is great for creating always-up-to-date computed values without writing application-level logic. You define it with an expression, and the database handles the rest, ensuring data consistency.
from django.db import models
from django.db.models import F
class Square(models.Model):
side = models.IntegerField()
area = models.GeneratedField(
expression=F('side') * F('side'),
output_field=models.BigIntegerField(),
db_persist=True
)
What are database-computed default values?
You can now define model field defaults that are computed by the database, not your application. This is done using the new db_default parameter on field definitions.
This matters for ensuring consistent default values are applied at the database level, which is crucial for data integrity, especially in concurrent environments.
from django.db import models
from django.db.models.functions import Now
class Article(models.Model):
title = models.CharField(max_length=200)
created = models.DateTimeField(db_default=Now())
How are field choice groups an improvement?
Field choices now support grouping with nested structures, making it easier to organize long lists of options in forms and admin interfaces. This is done using Choices with optgroup.
This cleans up the user experience significantly for fields with many categorical options, like country lists grouped by continent or product types by category.
from django.db import models
class Book(models.Model):
class Continent(models.TextChoices):
AFRICA = 'AF', 'Africa'
ASIA = 'AS', 'Asia'
class Europe(models.TextChoices):
NORTHERN = 'NE', 'Northern Europe'
WESTERN = 'WE', 'Western Europe'
What's simpler about form rendering now?
Rendering form fields is much simpler with the removal of the div wrapper. Form fields now use Django's template-based rendering by default instead of an older string-based method.
This gives developers more direct control over the HTML output without having to override complex widget rendering methods. It's a welcome change for frontend integration.
FAQ
Is the GeneratedField supported on all databases?
No. Currently, GeneratedField is supported on PostgreSQL, Oracle, and SQLite. Support for MySQL and MariaDB is not included in this release.
Can I use async with django.core.mail.send_mail() now?
Yes. The send_mail() function and related email helpers in django.core.mail now have asynchronous versions, prefixed with a, like asend_mail().
What should I use instead of the deprecated JSONField?
You should migrate to using django.db.models.JSONField, which has been the standard since Django 3.1. The old django.contrib.postgres version is now deprecated.
How do the new choice groups appear in the admin?
Choice groups defined with the nested class approach will automatically render as <optgroup> labels in <select> dropdowns in the Django admin interface.
What is the db_persist parameter for in GeneratedField?
It determines if the field is stored in the database (db_persist=True) or is a virtual field that is computed on read (db_persist=False). Stored fields can be indexed for faster queries.