16 May 2025
Django community aggregator: Community blog posts
Django News - Django News is at PyCon US this weekend! - May 16th 2025
Introduction
Django News is at PyCon US this weekend!
Jeff and Will are at PyCon US in Pittsburgh this weekend and would love to meet fellow Django enthusiasts. Drop by the DSF or JetBrains booth to say hello and connect with the many Django community members and DSF folks who will be around all weekend.
Django Newsletter
News
Google Summer of Code 2025 - Django Projects
Three projects out of many worth proposals were accepted. Improvements to Django admin, adding django-template-partials
to core, and automating processes in the Django contribution workflow.
Waiting for Postgres 18: Accelerating Disk Reads with Asynchronous I/O
Postgres 18 introduces asynchronous I/O with new io_method options (worker and io_uring), which can double or triple read performance in high-latency cloud environments.
Django Software Foundation
Simon Charette is the DSF member of the month
Simon Charette is a longtime Django contributor and community member. He served on the Django 5.x Steering Council and is part of the Security team and the Triage and Review team.
Updates to Django
Today 'Updates to Django' is presented by Abigail Afi Gbadago from the DSF Board and Djangonaut Space!🚀
Last week we had 10 pull requests merged into Django by 7 different contributors - including a first-time contributor! Congratulations to Safrone for having their first commits merged into Django - welcome on board!🎉
This week's Django highlights 🌟
- Security release of Django 5.2.1, 5.1.9 and 4.2.21.
- Field names have been added to hints in admin duplicated fields errors.
- Maximum bulk size for SQLite bulk_create and bulk_update methods now respect SQLITE_LIMIT_VARIABLE_NUMBER.
Django Newsletter
Wagtail CMS
Our four contributors for Google Summer of Code 2025
Four GSoC 2025 contributors will extend Wagtail with grid-aware sustainability, strict CSP compatibility, improved media listings, and enhanced keyboard shortcut accessibility.
Sponsored Link 1
Hire Django developers without the hassle!
Building a team of skilled Django developers has never been easier. Trust HackSoft to help you with strategic Django team augmentation. Learn more!
Articles
Django Security Best Practices: A Comprehensive Guide for Software Engineers
Enforce up-to-date Django versions, HTTPS, strong SECRET_KEY
, ORM usage, built-in security middleware, XSS/CSRF defenses, robust authentication, dependency auditing, logging, and monitoring.
18 Years of REVSYS
Revsys marks 18 years offering Python and Django expertise, including code reviews, architectural design, cloud migrations, Kubernetes, CI/CD, AI integration, and team training.
Django: model field choices that can change without a database migration
Use Django 5.0 callable choices to avoid no-op migrations when updating model field choices, though database constraints still require migrations for data integrity.
Algorithms: Learning One's Learnings
Use Big O notation to choose efficient sorting in Django apps, leveraging Python's built-in Timsort or Quick Sort instead of Bubble Sort to improve performance.
Birds and Angles: Dabbling in Django Components
Combining django-bird and dj-angles enables Web-component style reusable Django template components for cleaner syntax and improved readability, despite limited filter parsing for props.
Setting up NGINX Unit (and switching from uWSGI)
Switch Django apps from uWSGI to NGINX Unit using JSON configuration, add SECURE_PROXY_SSL_HEADER
, adjust socket proxy_pass, and enable ASGI/WSGI deployments.
My DjangoCon Europe 2025
Paolo Melchiorre recaps his DjangoCon Europe 2025 experience in Dublin through Mastodon posts covering keynotes, talks on testing, migrations, community events, and mentoring.
Tutorials
Rapid AI-powered applications with Django MongoDB and Voyage API
Learn how to build an LLM-powered recipe recommendation website with Django and MongoDB.
Podcasts
Django Chat #182: Event Sourcing with Chris May
Chris is a Senior Staff Engineer at WellSky, a software company in the health industry. We discuss his background as a graphic designer, learning Python (and Django) as an adult, his multiple conference talks on HTMX, why he's a fan of event sourcing, and more.
Talk Python #505: t-strings in Python (PEP 750)
A panel discussion of PEP 750 on t-strings, scheduled for Python 3.14, which build on the idea of f-strings
to produce a template object rather than a standard string.
Django News Jobs
Python / Django Software Developer - full-time at Off Duty Management 🆕
Backend Python Developer (Django/DRF) at Paytree
Django Newsletter
Projects
astral-sh/ty
An extremely fast Python type checker and language server, written in Rust.
pydantic/pydantic-ai
Agent Framework / shim to use Pydantic with LLMs.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
16 May 2025 3:00pm GMT
My second DjangoCon Europe
Well I have been meaning to write this for over 2 weeks now, but better late than never! Towards the end of April 2025 I attended the DjangoCon Europe conference and Sprints and it was brilliant and exhausting all in one go.
Let's begin with the travel there, I decided to join those doing the SailRail for a relaxed train ride and crossing the sea to Dublin. This was great as I managed to make some use of the day (work and a blog post) while travelling as well as having some travel companions in the form of Thibaud, Sage, Tom & Daniele.
The next day kicked off the conference with an excellent keynote from Sarah Boyce, and other talks followed thoughout the next 2 days. Databases was a big theme along with community engagement and HTMX. However for me it was walking into the room and meeting folks from the community in person, that I have interacted with online for the past couple of years. This was also coupled with great conversations with friends new & old (mostly around making Django better). I also plucked up the courage and gave a lighting talk on the last day about my year of 100 words.
The evening socials again were excellent! Django Social on Wednesday and the official party on Friday, with a more chill evening going climbing with a couple of interested attendees. The weekend brought the Sprints which were just perfect. I managed to crack on with an open ticket/PR I have for the messages app in Django and also make some good progress on django-prodserver.
It was sad to leave, but reminds me that I want to go next year (if I am allowed by the family!). I am also excited with the energy I felt across the week reminding me that Django is going strong as ever and the communuity has a bright future. I could write more, but I am aware that I need to crack on with today's work, but I will leave you with the recommendation of getting to a DjangoCon if are use Django in any form, you will not be disappointed.
16 May 2025 5:00am GMT
Pygrunn: team alignment, enterprise design power - Edzo A. Botjes
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
He helps startups to design their business. He's got more info at https://www.edzob.com/page/enterprise/ , an "enterprise design cheat sheet". He was a consultant for a long time and started noticing patterns. He's now in education/research and he's focused on culture.
According to Osterwalder, success = value proposition + uniqueness + business model + timing + team alignment. In Edzo's experience, the team alignment is often a core problem.
As a person, you have a skill set (behaviour and capabilities). As a team, you have a collective toolset: (structure, processes, data and tech). Those two are the tangible stuff. Intangible is your mindset (attitude and motivation) as a person, and the culture as a team.
UX is a social contract between an app and the user. There's a social contract behind the interactions within the company. A culture. How do you want to collaborate? How you collaborate defines what you're going to be building. Conway's law. (He mentioned his talk of last year about this subject).
His wife did a PhD about the meaning behind fairy tales. For him, as a technical person, the idea of having multiple meanings of the same physical text was initially hard. What do words mean? What is their purpose? Having good conversations about the terms and words used in, for instance, your business model/motivition canvas is a good idea. Communication is key.
There was a lot more in his presentation, as it was intended as a fast-paced talk. Lots of way to look at your business or product. But in the end, team alignment could well be key. Optimizing your team members. Organizing them well. Collaboration? Facilitating? Key: have conversations. "Invest in beer and bitterballen, not in courses".
And: you should always be looking at what can I destroy. What in your company can be stopped, removed, destroyed? You need that to change and improve.
His slides are online with lots of extra links and background information.

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
Pygrunn: python on a tractor - Wieneke Keller, Sebastian Lenartowicz
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
How to become an apple farmer in 5 minutes:
- You want mid-size apples, as they fetch the best price.
- You want blossom on your tree, but not too much. Otherwise the tree has to divide its water and nourishment over more apples, which makes them smaller...
They work at aurea imaging, maker of "treescout". The treescout is a device/camera on top of a tractor that drives along the apple trees in an orchard. The device detects the tree, blossoms and other attributes of the tree. The first use case: blossom thinning to aim at the right size of apples. Blossom thinning happens with a sprayer. The blossom blossoms for just two or three weeks.
The first season they tried their project was educational. Lots or problems :-) GPS tracks that were not straight. Detected trees were not in the right location. Etcetera.
Some of the challenges:
- It is on a vehicle, so limited power.
- It is on a farm, so very limited or no connectivity.
- Agricultural standards are actually from the maritime industry. GPS that is accurate within a few meters is fine, there. But not detailed enough for locating trees...
- They were a software company, so they had to use off-the-shelf components.
The first blossom season, their architecture looked like this:
- Python monolith with multiprocessing.
- Restarting upon failure was hard due to them using unix pipes for inter-process communication.
- Poor separation of responsibilities.
The second blossom season they changed several things.
- They used k3s (a lightweight kubernetes).
- A single-node k3s cluster sitting on top of a tractor.
- K3s is responsible for the runtime environment and workload management.
- Rabbitmq for inter-process communication.
- A Kubernetes cluster really helps with rolling out quick updates.
A problem they noticed is python's concurrency problem. There are some central components that are a bottleneck.
What they're working on:
- ArgoCD, open cluster management, kairos ("in-place os updates"), embedded linux. They're close to fully-automatic remote upgrades.
- More flexible hardware setup.
- Machine learning and insights on tree level. BIG amount of data for an eight-man dev team...
- Increasing the number of customers.

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
Pygrunn: how to solve a python mystery - Aivars Kalvāns
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
Aivars pointed at https://www.brendangregg.com/linuxperf.html as a good overview of linux tools
A good start is the /proc filesystem, you can use it to gather information on processes, for instance to grab the environment used by a process:
$ cat /proc/1234455/environ || tr '\0' '\n'
The files/sockets used by a specific process:
$ ls /proc/12345/fd/*
You might have an unfindable file that takes up lots of space (like a logfile that has been deleted from a directory, but that is still open in some program). The command above will have (deleted) next to deleted files, so you can search for that string in the output to find the process that still has such a big file open.
Another handy tool: strace, it traces linux system kernel calls. You don't even need root access if you just want to trace your own processes. An example command:
$ strace -f -ttt -o output.txt -s 1024 -p <PID> $ strace -f -ttt -o output.txt -s 1024 -p your-new-process.sh
If your code does a system call ("read something from somewhere"), strace prints both the start and the end of the call. So you can find out exactly where something is blocking in case of an error. He mentioned https://filippo.io/linux-syscall-table/ as a good overview of the available system calls you might see in the output.
Disk IO problems? Try iostat -x to see where the IO is happening. When testing disk throughput, don't just test huge blobs of data, but make sure to use the actual block size (often 4k or 8k).
When debugging network access, you often use ping or traceroute. But both use protocols (ICMP and UDP) that are often blocked by network admins. He suggests tcptraceroute which uses TCP and often gives a better view of reality.
With network problems, TCP_NODELAY is a possible cause. See https://brooker.co.za/blog/2024/05/09/nagle.html for more information. Read this especially when you see the magic number 40ms in your logs, or only get 25 transactions per second.
Tip: set timeouts for everything. The defaults are often a cause for hanging.

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
Pygrunn: django template LSP, smarter completion for django templates - Kees Hink
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
Henk works at four digits, a long-time django shop.
He had a poll at the start about peoples' favourite editor. The top three: pycharm 38%, vscode 37%, neovim 11%. (Bugger, my favourite, emacs, is not in the top three).
Code completion is nice. Modern editors are real handy for this with good support for django and python. But... for django templates, it is missing. No auto-completion for {% bl to {% block. And also no knowledge of the available variables and attributes.
Pycharm is an exception, it has django language support and completion for the standard django template tags and also auto-complete in case you have class-based views.
He showed us django template LSP: https://github.com/fourdigits/django-template-lsp, wich implements similar functionality for most other editors.
- It also picks up custom template tags.
- Docker support! It can find your template tags and code inside a docker image.
- When something is not picked up, you can add a comment with a type hint.
- You can install it from vscode, the name is djlsp.
You can build such a LSP, Language Server Protocol, yourself. LSP allows a client (your IDE) to interface with the language server. "A document is opened", "I'm on line x, character y, is there a hint here?".
They have a script called django-collector.py that is run with your project's python (with a fallback). It statically analyses your code and returns json for use by the rest of the LSP mechanism.
There's an alternative, django language server, started a while after they themselves started their LSP. Written in rust. But there's not a lot of functionality yet.
Django template LSP is open source, it is in their github repo. They're using it a lot internally. If you have ideas and pull requests: welcome!

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
Pygrunn: cloud native geospatial formats for field boundaries - Ivor Bosloper
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
Cloud native geospatial file formats:
- Geospatial data: you have raster data (= images) and vector data. And point data.
- Raster data: geotiff, png, jpg. Vector: (shapefiles), gpkg, geoparquet. Points: gpkg, geoparquet.
Cloud native? Let's look at geotiff for instance. Just the old .tiff format, so a raster of pixels with some metadata. A geotiff has metadata like extent, projection, etc. There is a cloud native variant, cloud optimized geotiff.
- You have tiles, so the big image is subdivided into tiles for easier/cheaper/faster loading.
- There are also multiple versions of the image at various "zoom levels".
- The metadata is always at a fixed place in the file, right at the front or at the back.
Such a cloud optimized format means that it is optimized for remote geospatial access patterns. The way it happens is with "http range requests". After reading the metadata for the file, the algorithm knows which parts of the big file to request from the server with such a http range request.
He wanted to do the same for vector data. An approach is GeoParquet. Parquet is a bit of a "csv format", simplified. For speed reasons it is subdivided in blocks. In the geospatial version, the blocks have an extent. (An extent is the min/max boundary around the data, btw).
Before cloud native geospatial formats, you really needed to have s special server program to host them, like geoserver. Geoserver is nice, but it is also a huge java program with loads of options. (And most people forget to properly secure it...)
What you can do now is that you can just store your cloud-native geopspatial file online in for instance s3. As long as it supports http range requests, you're set. The big advantage is that there are good specifications and lots of implementations.
He's now working on FIBOA: FIeld BOundaries for Agriculture. An open source and open data project. There are many open data portals with agricultural field boundaries. But all of them have different formats. FIBOA wants to unify all that. See https://github.com/fiboa/specification
For converting the current local data to their format, they used lots of python and (geo)pandas. They're trying to generalize the python+geopandas+extract+export process, as it seems handy for lots of other use cases: https://github.com/vecorel/

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
Pygrunn keynote: Homo ludens, python and play - Daniele Procida
(One of my summaries of the 2025 pygrunn conference in Groningen, NL).
Organizing a conference is a weird mix between it-is-not-my-job and it-is-a-lot-of-real-work.
When Daniele Procida learned python 16 years ago, he was often told that learning python is fun! And it is easy! Often when people say it is fun and easy, that you should be suspicious.
It actually wasn't fun. There was lots of satisfaction, though. Solving problems is nice. He didn't want to have fun and he didn't want to be a great programmer: He just wanted to solve problems!
Fun, playful... Python early on had a bit of playfulness. Named after Monty Python, an old BBC comedic television series. Nowadays most people haven't seen Monty Python on television and actually discover it through the programming language. How does an Indonesian teenager react to the unknown Monty Python jokes?
Same with python-the-snakes. Lots of book with snakes on the cover. Some playful, some aggressive. Some with dripping venom (that doesn't fit with a constricting type of snake...). But try talking about "python" in African countries where Pythons actually are a menace...
His definition of humor: the surprising violation of an expectation of congruity. A momentary re-ordering of the world. It gives us a surprising delight.
Python itself is full of expectations that can be violated... He was originally baffled by the term "pythonic": he was just wondering whether his code worked or not, he didn't expect his code to be judged on some fit-in-with-the-locals quality like "pythonic".
An exception means you need a rule. A holiday is something different than regular days. A "holiday from the rule". The special depends on the normal. Fun is a "holiday from seriousness". Then: how can "fun" be made the expectation? A constant low-level fun is not funny.
Johan Huizinga wrote "homo ludens" in 1938. Homo ludens, the playing man. See wikipedia. He says that play is the primary pre-condition of culture. But how? According to Daniele's examples, the holiday can't come before the work. You need to have an exception when there's a normal. God rested on the seventh day, but that only could be rest because he actually worked for six days.
Culture? Players on a stage. Which has rules. A courtroom can be a sort of playground. A kids' playground has some boundaries. Could there be something to Huizinga's argument?
At work, you can receive clear outcomes: recognition, rewards. The same system offers penalties. Work is a relatively clear system. A framework of rewards, value, etc. Daniele likes his work (he works for canonical/ubuntu). He's allowed to collaborate a lot.
What can compete with that? In the weekend or the evenings? Often what you do is unclearer. When is it finished? When did you do a good job? To do something at home, he has to get tools out of the garage and he has to clean up afterwards: just grabbing a laptop at work is much easier. Grabbing his guitar takes more work. And nobody thanks him for playing on it. It can be too much work even to take a holiday from work. To play.
Easy-to-start-with work with good feedback is always easily available...
There's an asymmetry of performance, failure and accountability. At work, you can get negative feedback. At home, what are they going to do? Sack him? No. Why are people talking about gamifying work? They should be talking about "workifying"! That's more attractive!
Open source: is it work or a labour of love? What about people pestering an open source project with unwanted contributions? The dance between maintainer and contributor. What when a state actor manages to get a malicious patch into a central piece of open source software (like what happened last year)?
Does this have to do with the difference between work and play? Could open source software benefit by some explicit rules, some explicit expectations? Social expectations?

Photo explanation: picture from our Harz (DE) holiday in 2023
16 May 2025 4:00am GMT
14 May 2025
Django community aggregator: Community blog posts
Event Sourcing - Chris May
- Everyday Superpowers*
- Chris on Fosstodon and BlueSky
- Why I Finally Embraced Event Sourcing and You Should Too
- DjangoCon US 2023: HTML-ivating your Django web app's experience with HTMX, AlpineJS, and streaming HTML
Sponsor
This episode was brought to you by HackSoft, your development partner beyond code. From custom software development to consulting, team augmentation, or opening an office in Bulgaria, they're ready to take your Django project to the next level!
14 May 2025 4:00pm GMT
13 May 2025
Django community aggregator: Community blog posts
My DjangoCon Europe 2025
A summary of my experience at DjangoCon Europe 2025 told through the posts I published on Mastodon during the conference.
13 May 2025 3:00am GMT
09 May 2025
Django community aggregator: Community blog posts
Django News - Python 3.14.0 beta is here - May 9th 2025
News
Python 3.14.0 beta 1 is here!
Python 3.14.0 beta1 brings deferred annotation evaluation, template string literals, Zstandard compression support, zero-overhead debugging, improved diagnostics, and invites Django projects to test compatibility.
Python Software Foundation Names New Deputy Executive Director
Python Software Foundation promotes Loren Crary to Deputy Executive Director, expanding her strategic planning, budgeting, sponsorship revenue development, and PyCon US support.
Announcing Python Software Foundation Fellow Members for Q1 2025! 🎉
PSF announces Q1 2025 Fellows, honoring outstanding Python community leaders and mentors who drive library development, education, and ecosystem growth.
Django Software Foundation
New Features GitHub repo and project
Django is experimenting with a new GitHub repository specifically designed to manage feature ideas and their progression. This is a significant shift away from the previous process of posting those to the forum.
Updates to Django
Today 'Updates to Django' is presented by Abigail Afi Gbadago from the DSF Board and Djangonaut Space!🚀
Last week we had 7 pull requests merged into Django by 6 different contributors - including a first-time contributor! Congratulations to 신우진 for having their first commits merged into Django - welcome on board!🎉
This week's Django highlights 🌟
- A bug in composite primary key introspection that caused an
IntegerField
to be wrongly identified asAutoField
on SQLite has been fixed. - A regression in Django 5.2 that caused a redundant
unique_together
constraint to be generated for composite primary keys when usinginspectdb
has been fixed. - The importance of the order of foreign keys on an intermediary model having self-referential many-to-many relationship has been clarified in the docs.
Special thanks to Clifford Gama for the long work on the PR 🥳
PyCon Italia will have a presentation on Djangonaut Space, Django girls, and the DSF with Paolo, Raffaella, Sarah and Sheena. It's a free event and all are welcome - don't miss out! https://2025.pycon.it/en/event/djangonauts
Django Newsletter
Wagtail CMS
Flying into a new era with Wagtail 7.0
The newest release cleans up a lot of cruft and takes Wagtail one step closer to autosave.
Sponsored Link 1
AI-Powered Django Development & Consulting
REVSYS specializes in seamlessly integrating powerful AI technologies, including GPT-4, into your existing Django applications. Your Django project deserves modern, intelligent features that enhance user engagement and streamline content workflows.
Articles
Making PyPI's test suite 81% faster
Optimizing Warehouse's test suite via pytest-xdist parallelization, Python 3.12 sys.monitoring
, testpaths, and import pruning cut execution from 163 to 30 seconds.
Maps with Django⁽³⁾: GeoDjango, Pillow & GPS
A quick-start guide to create a web map with images, using the Python-based Django web framework, leveraging its GeoDjango module, and Pillow, the Python imaging library, to extract GPS information from images.
GeoDjango: PostgreSQL Triggers for GeoJSON Handling
Utilize django-pgtrigger
and PostgreSQL JSON functions to auto-populate GeoDjango MultiPolygonField
from GeoJSON stored in a JSONField on insert or update.
pre-commit: install with uv
Use uv tool mechanism to install and manage pre-commit globally, accelerating Python hook installs, upgrades, and Django project Git hook workflows.
What IS a Django App?
Django apps encapsulate modular, reusable subsystems within projects, improving code organization, testability, admin interface clarity, and simplifying transitions to microservices.
Keynoting DjangoCon EU
Mia Bajić gave the day 2 keynote talk on "The Most Bizarre Software Bugs in History." Here she recounts her full conference experience: talks, events, and even swimming in the ocean after the first day of sprints.
Vibe Recap of DjangoCon Europe 2025 - Will Vincent
A photo-filled recap of the conference, social events, and more.
DjangoCon Dublin - Raffaella Suardini
A recap focusing on the Django Girls workshop, talk highlights, and more.
DjangoCon Europe 2025 Review
The review highlights keynotes, DSF board Q&A, networking opportunities, lightning talks, and community engagement at DjangoCon Europe 2025 in Dublin.
Events
DjangoCon Africa Tickets now available
DjangoCon Africa is August 11th-15th in Arusha, Tanzania. Early bird tickets are available for a limited time, so don't miss out on the special rates.
Videos
"Djangonaut Space: A Mentorship Program For Open Source" - Lilian
Djangonaut Space is a mentorship program that bridges the gap between new contributors and long-time maintainers, helping sustain Django's ecosystem. Its fourth session offers insights for anyone interested in building a thriving open-source community.
Sponsored Link 2
Sponsor Django News
Django News Jobs
Backend Python Developer (Django/DRF) at Paytree 🆕
Django Newsletter
Projects
django/new-features
New feature proposals for Django and third-party ecosystem.
See the DSF's recent New Features GitHub repo and project blog post.
wq/django-rest-pandas
Serves up Pandas dataframes via the Django REST Framework for use in client-side (i.e. d3.js) visualizations and offline analysis (e.g. Excel).
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
09 May 2025 3:00pm GMT
03 May 2025
Django community aggregator: Community blog posts
Django: model field choices that can change without a database migration
Adam Hill posted a question on Mastodon: he wants a model field that uses choices
that doesn't generate a database migration when the choices change. This post presents my answer. First, we'll recap Django's default behaviour with choice fields, a solution with callable choices, and the drawbacks.
The default behaviour
Take this model definition:
from django.db import models
class Colour(models.IntegerChoices):
TEAL = 1, "Teal"
class Flower(models.Model):
colour = models.IntegerField(choices=Colour.choices)
The enumeration type Colour
is used for the choices
of the model field Flower.colour
. Colour.choices
returns a list of tuples that contain values and labels.
Run makemigrations
to create the initial migration for this model:
$ ./manage.py makemigrations example
Migrations for 'example':
example/migrations/0001_initial.py
+ Create model Flower
And check the generated migration:
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Flower",
fields=[
("id", models.BigAutoField(...)),
("colour", models.IntegerField(choices=[(1, "Teal")])),
],
),
]
The colour
field definition includes the serialized list with one choice: (1, "Teal")
.
Then, say we make a change to Colour
:
class Colour(models.IntegerChoices):
TEAL = 1, "Teal"
+ PUCE = 2, "Puce"
makemigrations
detects the change and generates a new migration:
$ ./manage.py makemigrations example
Migrations for 'example':
example/migrations/0002_alter_flower_colour.py
~ Alter field colour on flower
With contents:
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("example", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="flower",
name="colour",
field=models.IntegerField(
choices=[(1, "Teal"), (2, "Puce")],
),
),
]
We can see the whole list of choices has been serialized again.
Run sqlmigrate on that migration:
$ ./manage.py sqlmigrate example 0002
BEGIN;
--
-- Alter field colour on flower
--
-- (no-op)
COMMIT;
The BEGIN
and COMMIT
statements are the start and end of a transaction. But in between, there's nothing but comments, including "(no-op)", meaning "no operation". So this migration does not change the database at all. It exists only for Django's internal state tracking.
Such no-op migrations can be a bit of a nuisance, especially when the list of choices changes often. They unnecessarily lengthen the migration history, which is what Adam Hill wanted to avoid.
A solution with callable choices
Django 5.0 extended choices
to support callables: functions and classes with a __call__
method. Since the migrations framework will then serialize the callable instead of the choice list, we can use this to avoid the no-op migration. Let's carry on the above example to see how this works.
First, introduce a function that returns the .choices
list, and use it for choices
in the model field:
from django.db import models
class Colour(models.IntegerChoices):
TEAL = 1, "Teal"
PUCE = 2, "Puce"
def get_colour_choices():
return Colour.choices
class Flower(models.Model):
colour = models.IntegerField(choices=get_colour_choices)
Then, run makemigrations
again:
$ ./manage.py makemigrations example
Migrations for 'example':
example/migrations/0003_alter_flower_colour.py
~ Alter field colour on flower
The migration uses the "serialized" function by importing it:
import example.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("example", "0002_alter_flower_colour"),
]
operations = [
migrations.AlterField(
model_name="flower",
name="colour",
field=models.IntegerField(choices=example.models.get_colour_choices),
),
]
Then, we can change Colour
again:
class Colour(models.IntegerChoices):
TEAL = 1, "Teal"
PUCE = 2, "Puce"
+ SALMON = 3, "Salmon"
But now, makemigrations
detects no changes:
$ ./manage.py makemigrations example
No changes detected in app 'example'
This is because get_colour_choices
still exists with the same name, and the import path is all the history tracks.
Drawbacks
I can think of two drawbacks to this approach.
1. The no-op behaviour of choices
is not guaranteed
The premise that choice-changing migrations are avoidable churn depends on them not affecting the database. But this fact is field-dependent.
Field classes may use choices
to determine the column definition, which they should declare in Field.non_db_attrs. An example is the EnumField
in django-mysql, which uses choices
for the MySQL/MariaDB ENUM
data type. In this case, migrations need to change the database to update which values are allowed there.
That said, none of Django's built-in fields (currently) do this.
2. Ideally, choices should be enforced with a CheckConstraint
In 2020, I covered how choices
aren't enforced unless you add a CheckConstraint
, a data integrity gotcha. I stand by the belief that nearly all fields using choices
should come with a matching CheckConstraint
, like:
from django.db import models
class Colour(models.IntegerChoices):
TEAL = 1, "Teal"
class Flower(models.Model):
colour = models.IntegerField(choices=Colour.choices)
class Meta:
constraints = [
models.CheckConstraint(
condition=models.Q(colour__in=Colour.values),
name="%(app_label)s_%(class)s_colour_valid",
)
]
Doing so prevents invalid data from being saved to the database:
In [1]: Flower.objects.create(colour=33)
...
IntegrityError: CHECK constraint failed: example_flower_colour_valid
In this case, any time you change the choices class, the check constraint will need a migration to propagate updates to the database, like:
$ ./manage.py makemigrations example
Migrations for 'example':
example/migrations/0002_remove_flower_example_flower_colour_valid_and_more.py
- Remove constraint example_flower_colour_valid from model flower
~ Alter field colour on flower
+ Create constraint example_flower_colour_valid on model flower
Since this would be needed, the "churn" for the field change is less of a problem.
Fin
In conclusion, using callable choices
allows you to avoid some migrations when choices change. But it won't help if you propagate choices to the database, which I think is generally a good idea. Still, it might be useful when the choice list is more dynamic, such as from a changing data source, or when choices are used for forms only, and arbitrary values should still be allowed in the database.
May you always choose wisely,
-Adam
03 May 2025 4:00am GMT
02 May 2025
Django community aggregator: Community blog posts
Django News - Template Tricks, DjangoCon EU, and Community Wins - May 2nd 2025
News
Djangonaut Space: Taking a Session Break
Djangonaut Space is temporarily pausing its mentoring sessions to develop stronger, more sustainable processes and is calling on Django developers to contribute code, volunteer, and donate.
Django Fellow Report
Django Fellow Report - Sarah Boyce
Sarah was at DjangoCon Europe last week, where she gave a keynote talk on the opening day. She also triaged 4 tickets, reviewed 6 more, and handled several miscellaneous items. Our Fellows do incredible work to so that Django can continue to thrive.
Django Fellow Report - Natalia Bidart
10 tickets triaged, 4 tickets reviewed, 2 authored, plus other tasks. Our Fellows write weekly notes on their work, and it's worth taking a glance to see the incredible work they do, mainly behind the scenes, to keep Django running smoothly.
Updates to Django
Today 'Updates to Django' is presented by Abigail Afi Gbadago from the DSF Board and Djangonaut Space!🚀
Last week we had 14 pull requests merged into Django by 13 different contributors - including 3 first-time contributors! Congratulations to 9r0k, Matti Pohjanvirta and dbogar89 for having their first commits merged into Django - welcome on board! 🎉
This week's Django highlights 🌟
- The type
EmailAlternative
has been updated to be serializable. - A breaking change in Django 5.2 has been reverted which effected custom admin templates
Object tools
section. - A [custom target directory will be created if missing in startproject and startapp] (https://github.com/django/django/pull/18387).
Special thanks to Bruno Alla for the long work on the PR 🥳
Django Newsletter
Wagtail CMS
DjangoCon Europe 2025 vibes and photos
Wagtail core team attended DjangoCon Europe 2025, showcasing new meta-framework ideas, MFA, AI training talks, hosted a meetup on migration/testing, and contributed sprint improvements.
Sponsored Link 1
Hire Django developers without the hassle!
Building a team of skilled Django developers has never been easier. Trust HackSoft to help you with strategic Django team augmentation. Learn more!
Articles
Quirks in Django's template language
The Django template engine exhibits quirks such as scientific notation issues, unsafe content conversion with upper filter, and inconsistent exception handling in if tags.
Silencing Disallowed Host Errors in Django
Django developers can mitigate DisallowedHost
logging errors in Sentry by leveraging Sentry's ignore_logger
function, reducing noise and preserving error quota.
/usr/bin/just do it
Just streamlines project command management by replacing heterogeneous scripts with intuitive, composable recipe commands that simplify automation.
Django and Postgres for the Busy Rails Developer
This article compares Django and Rails database workflows, highlighting Django's automatic migration generation, idiomatic Postgres integration, and efficient toolchain management in real-world projects.
My First DjangoCon: Lessons, Nerves, and Unforgettable Moments
Thoughts on attending DjangoCon Europe for the first time as both an attendee and a speaker.
Takeaways from DjangoCon EU 2025
DjangoCon EU 2025 insights cover advanced database tuning, ORM optimization, performance testing strategies, and innovative best practices for enhanced Django applications.
Python type hints: mixin classes
Adam Johnson provides a typically wise overview of mixin classes with a number of hints on how to use them properly.
Event Sourcing: Reactivity Without the React Overhead
The fourth entry in a five-part series on event sourcing, an architectural pattern where state changes in your application are represented as a sequence of immutable events, rather than being persisted directly in the database as the current state.
Events
⌛ Last call to speak at DjangoCon US 2025 (ends May 4th)
Time is running out! Submit your talk proposal for DjangoCon US 2025 by May 4th and share your knowledge with the Django community in Chicago this September!
Tutorials
Matching auto-imports in Django 5.2 to django-extensions
Django 5.2 now supports built-in auto-imports for models, enabling developers to customize imports via overriding management commands and replicate django-extensions shell_plus
functionality.
Running Background Tasks from Django Admin with Celery
Integrating Celery with Django admin enables asynchronous execution of long-running tasks, improving web app responsiveness using Docker Compose and Redis.
Podcasts
Django Chat #181: DjangoCon Europe 2025 Recap
A quick recap episode sharing thoughts and highlights from attending DjangoCon Europe last week in Dublin, Ireland. We both gave talks and shared favorites from the official schedule, social events, and hallway track highlights.
Talk Python #502: Django Ledger - Accounting with Python
An interview with Miguel Sanda, creator of Django Ledger, a double-entry accounting system and financial analysis engine built on the Django Web Framework.
Django News Jobs
Senior Full Stack Web Developer (Python/Django + CMS) at VanNoppen Marketing
Django Newsletter
Projects
Salaah01/django-action-triggers
A Django library for asynchronously triggering actions in response to database changes. It supports integration with webhooks, message brokers (e.g., Kafka, RabbitMQ), and can trigger other processes, including AWS Lambda functions.
meilisearch/meilisearch
A lightning-fast search engine API bringing AI-powered hybrid search to your sites and applications.
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
02 May 2025 3:00pm GMT
01 May 2025
Django community aggregator: Community blog posts
Algorithms: Learning ones Learnings
When I studied algorithms more than twenty years ago, I saw their general usefulness, but since then, I have never had to use them in the real world because they had already been implemented by database management services or built-in functionalities of most programming languages that I used.
Interviewer: Can you sort this list by size?
Interviewee: Absolutely.
/types confidently.../
l.sort()
There came a time when I had to remind myself of sorting algorithms. At 1st things 1st, I was about to implement a feature that lets users prioritize their options by comparing them two at a time. I thought that the Bubble Sort algorithm would fit perfectly.
So, I built the UI using ReactJS and Django for the backend to let users compare options and sort their priorities.
However, I soon noticed a problem: for longer lists, the process became quite time-consuming for users.
One day, I remembered something about algorithm complexity (also known as Big O Notation) and realized that Bubble Sort isn't the most efficient choice for this task.
In computer science, Big O notation describes how the performance of an algorithm grows relative to the size of the input. It's usually written like O(value)
, where value
is a function of n
, and n
is the number of items the algorithm processes.
For example:
- Finding the first item in a list or a key in a dictionary of n items is
O(1)
. - Summing all items by iterating through a list is
O(n)
. - Using a triple nested loop over the list would result in
O(n³)
.
Here is an overview of most common complexities:
Complexity | Name | Meaning and Example |
---|---|---|
O(1) |
Constant | Always the same time, no matter input size, e.g. accessing an array item |
O(log n) |
Logarithmic | Doubles size, just +1 step, e.g. Binary Search |
O(n) |
Linear | Time grows with size, e.g. loop over list |
O(n log n) |
Linearithmic | "Almost linear", but a bit slower, e.g. Merge Sort |
O(n²) |
Quadratic | Time explodes with size, e.g. nested loops as in Bubble sort |
O(2ⁿ) |
Exponential | Be careful - grows crazy fast, e.g. Recursive Fibonacci |
O(n!) |
Factorial | Nightmare mode, e.g. solving Traveling Salesman by brute force |
Understanding the Big O practically
Bubble Sort is an algorithm with a time complexity of O(n²)
. That means: if you have a list of items, the algorithm needs to compare each item against many others, using two nested loops.
- To sort a list of 5 items, the user might need up to 25 comparisons.
- To sort 10 items, up to 100 comparisons.
- To sort 50 items, up to 2,500 comparisons.
Not ideal.
I asked ChatGPT to help evaluate sorting algorithms based on their complexity, and Quick Sort came out as a much better choice. Its complexity is O(n log n)
, where log n
(base 2) roughly means "how many times you can divide n
by 2 until you reach 1."
- To sort 5 items, Quick Sort would need around 12 comparisons.
- To sort 10 items, around 34 comparisons.
- To sort 50 items, around 282 comparisons.
That's still some work, but much more manageable.
From a usability perspective, though, it's even better to let users drag and drop items manually or to offer AI-suggested orderings. So I implemented those options too.
Algorithm complexities in action
Below is a quick cheat sheet with complexities from the fastest to the slowest:
Sorting algorithms
Algorithm | Best Case | Average Case | Worst Case | Notes |
---|---|---|---|---|
Timsort | O(n) |
O(n log n) |
O(n log n) |
Used in Python, Java |
Merge Sort | O(n log n) |
O(n log n) |
O(n log n) |
Stable, reliable |
Heap Sort | O(n log n) |
O(n log n) |
O(n log n) |
In-place |
Quick Sort | O(n log n) |
O(n log n) |
O(n²) |
Fastest on average |
Shell Sort | O(n log n) |
O(n¹·⁵) |
O(n²) |
Improved insertion |
Insertion Sort | O(n) |
O(n²) |
O(n²) |
Good for small/mostly sorted data |
Selection Sort | O(n²) |
O(n²) |
O(n²) |
Simple but slow |
Bubble Sort | O(n) |
O(n²) |
O(n²) |
Only good for tiny lists |
Search algorithms
Algorithm | Best Case | Average Case | Worst Case | Notes |
---|---|---|---|---|
Hash Table Search | O(1) |
O(1) |
O(n) |
Worst case rare (collisions) |
Binary Search | O(1) |
O(log n) |
O(log n) |
Needs sorted data |
Jump Search | O(1) |
O(√n) |
O(√n) |
For sorted arrays |
Ternary Search | O(1) |
O(log n) |
O(log n) |
Split into three parts |
Linear Search | O(1) |
O(n) |
O(n) |
No sorting needed, but slow |
Encryption algorithms
Algorithm | Complexity | Notes |
---|---|---|
AES (Advanced Encryption Standard) | O(1) per block |
Very fast, symmetric key |
ChaCha20 | O(1) per block |
Modern stream cipher, very fast |
RSA Encryption | O(n³) |
Public key, slow for big data |
Elliptic Curve Cryptography (ECC) | O(n²) |
Faster than RSA at similar security |
Diffie-Hellman Key Exchange | O(n³) |
Secure key exchange, slower |
Just for the hunger of interest
Python, MySQL, and PostgreSQL use these algorithms behind the scenes:
System | Sorting Algorithm | Notes |
---|---|---|
Python sort() and sorted() |
Timsort | Hybrid of Merge Sort + Insertion Sort |
MySQL ORDER BY |
Quicksort (small datasets), Merge Sort or Filesort (large datasets) | Depends on storage engine (InnoDB, etc.) |
PostgreSQL ORDER BY |
Quicksort (small data), Heapsort + Mergesort for bigger sets | Intelligent memory-aware switching |
Final words
So if you ever have to solve a development issue algorithmically instead of using default libraries - or even when choosing an algorithm from a library - remember the Big O notation. Sometimes the difference can save milliseconds or seconds of time, and sometimes, when users' input is involved, it can save minutes or even hours.
Cover picture by Steve Johnson
01 May 2025 5:00pm GMT
30 Apr 2025
Django community aggregator: Community blog posts
DjangoCon Europe 2025 Recap
- DjangoCon Europe 2025
- DjangoCon Europe on YouTube - subscribe to be notified when talks are posted
- Get Started With AI Assistant in PyCharm
- neapolitan - Quick CRUD views for Django
- Django Social
- Django Events Foundation of North America
30 Apr 2025 4:00pm GMT
25 Apr 2025
Django community aggregator: Community blog posts
Django News - Revamp Your Django Admin and Supercharge Search - Apr 25th 2025
News
See you at PyCon US in Pittsburgh!
Django invites community members to visit and volunteer at its PyCon US 2025 booth in Pittsburgh for stickers and project engagement.
2025 PSF Board Election Schedule Change
Starting in 2025, PSF will move board election timelines to August and September to relieve PyCon US planning pressures and give candidates more campaign time.
Django Software Foundation
Django Admin Theme Roundup 2025
Explore a curated roundup of customizable Django Admin themes like Dracula, Jazzmin, Unfold, Simple UI and others for refreshed backend UIs.
Wagtail CMS
Check yourself before you wreck yourself with vibe coding
AI-powered vibe coding accelerates app development but demands rigorous security practices like secret management, input validation, and leveraging frameworks such as Django for safer production deployments.
Hot takes are making the planet hotter (and we can do something about it) 🌍
Wagtail-driven Django sites can cut carbon footprints by adopting WebP/AVIF images, greener hosts, responsible AI, dark mode, and cleaning up old content.
Sponsored Link 1
The #1 Django Podcast
Since 2019, Django Chat is a biweekly podcast covering the people and news behind Django. Hosted by former Django Fellow Carlton Gibson and LearnDjango founder Will Vincent.
Articles
14 Advanced Python Features
Explore fourteen advanced Python features: typing overloads and generics, context managers, metaclasses, and other tools to boost code safety, performance, and readability.
Python's new t-strings
Python 3.14 will introduce template strings (t-strings) that produce Template objects enabling safe, flexible string interpolation to prevent injection issues.
You don't need CompositePrimaryKeys
Django 5.2 adds CompositePrimaryKey support for legacy or sharded databases, but new models should avoid composite keys in favor of surrogate keys and unique constraints.
Quick Mastodon toot templates for event hashtags
Prepopulate Mastodon toots with event hashtags by creating share URLs and saving a GitHub Gist shortcut to your mobile home screen.
Grab a Pint With Django-MongoDB-Backend, Voyage AI, and LangChain
A very detailed overview of building a Dublin City Center Pub Finder app built using MongoDB's new Django Backend Python package, Voyage AI embeddings to best understand the queries, and LangChain to power the natural-language interface.
Tutorials
Running Background Tasks from Django Admin with Celery
A tutorial looking at how to run background tasks directly from Django admin. It uses Celery, but similar concepts apply to any other task queues, such as Django-RQ, Django Q, or Huey.
How to Add Blazing Fast Search to Your Django Site with Meilisearch
Integrate Meilisearch into Django to implement blazing fast, typo-tolerant search with unified schemas, Pydantic validation, automatic indexing mixins, and management commands.
Videos
How to Identify Unused Images in Wagtail CMS
Use Wagtail's built in image usage metrics to pinpoint and purge unused images from your CMS library, keeping the file store lean and current.
Sponsored Link 2
Sponsor Django News
Django News Jobs
Senior Full Stack Web Developer (Python/Django + CMS) at VanNoppen Marketing
Django Newsletter
Projects
bahdotsh/wrkflw
Validate and execute GitHub Actions workflows locally.
radiac/django-style
Basic tasteful designs for your Django project.
Sponsorship
🌟 Sponsor Django News
Are you interested in connecting with a vibrant community of 4,150 active Django developers? We have sponsorship opportunities for this spring and the upcoming summer season. Reach an engaged audience and support the Django community!
Django Newsletter
This RSS feed is published on https://django-news.com/. You can also subscribe via email.
25 Apr 2025 3:00pm GMT