Why We Started Building on the Django 6.1 Alpha


Mariusz Felisiak
Backend Engineer
Introduction
In May of this year, we had to make a decision about the tech stack for new things that we were going to build at Divio.
For many years Divio has been engaged in the Django community - among other things, by sponsoring DjangoCons and bringing Django people together. That's why the Django framework was an obvious choice for us. The key question was which version to use. Stick with the latest LTS (5.2), use the latest released version of Django (6.0), or be on the bleeding edge and start building things based on the still hot pre-release of Django 6.1. Literally on the first alpha version, released on 20 May. We decided on the last.
Why We Test Pre-Releases
During my five years as a Django Fellow and release manager, I spent a lot of time trying to persuade people to test pre-release versions, help find bugs in the new features, and give something back to Django itself. Testing pre-release versions is a great way to contribute to the framework we all love. Now that I'm on the other side, making this effort is not up for discussion, it's a must-have. That's how we ended up not just using the pre-release of Django 6.1 but developing against the stable/6.1.x branch, which forks from main at the alpha feature freeze:
[tool.uv.sources]
django = { git = "https://github.com/django/django.git", branch = "stable/6.1.x" }The Features We Wanted
Django 6.1 introduced a "harmonious mélange" of new features that we really wanted to use:
Database-level delete options for
ForeignKey.on_delete- no more collecting related objects on the Python side. With Python-level delete options, Django cascades through every related object, loads them into memory, and deletes them one by one. The database then runs similar queries again to check its foreign key constraints and protect data integrity. That double effort gets expensive when an object has a lot of relations (we all have users, right). Database-level delete options move the work to where it belongs - the database, which is designed to do it efficiently.Admin actions on the admin change form - the same actions can finally be reused on both the change and list views, making the Django admin even more extensible.
UUID7()database function - a perfect match for non-sequential primary keys that are still orderable and filterable by date, another performance boost.DecimalField()with no precision -max_digitsanddecimal_placesare no longer required on PostgreSQL, SQLite and Oracle, so you can define a decimal column without committing to a precision up front.
And many others.
The Bugs We Found
The most heartwarming thing is that during the development we were able to notice, report, and fix bugs in the newest Django that was still under development:
Using
UUID7()as a database default on a primary key crashed the admin's add page whenever the model had inlines #37139The same setup broke saving inline rows, because the empty inline form rendered an internal object as the parent value #37147
Read-only admin fields with a database default displayed that internal object instead of showing as empty #37168
The new
Actionclass could not be imported fromdjango.contrib.admin, unlike its companionActionLocation#37176
We tested Django 6.1 every day and caught issues immediately.
Django 6.1 was released on 5 August. All hands on deck, folks! Try Django 6.1 today and share your personal favorites.
If you want to try it on a deployed app, our Django template gets you running in a few minutes. Start a free trial and see how it behaves in the cloud.