Published: Wed 17 March 2021
Iuri de Silvio
I started contributing to Django core after a failure in our project.
I had to rename a model attribute without touching our database. The solution
# Simple attribute to rename.
author = models . ForeignKey ( 'Author' )
# 1. Add db_column param.
author = models . ForeignKey ( 'Author' , db_column = 'author' )
# 2. Change the attribute name.
creator = models . ForeignKey ( 'Author' , db_column = 'author' )
It was really obvious to me that it should be a noop to database. Even Stack Overflow
had a response confirming that.
The first migration locked our database because it dropped and recreated a constraint.
SET CONSTRAINTS "core_book_author_id_eaa1580d_fk_core_author_id" IMMEDIATE ;
ALTER TABLE "core_book" DROP CONSTRAINT "core_book_author_id_eaa1580d_fk_core_author_id" ;
ALTER TABLE "core_book" ADD CONSTRAINT "core_book_author_id_eaa1580d_fk_core_author_id"
FOREIGN KEY ( "author_id" ) REFERENCES "core_author" ( "id" ) DEFERRABLE INITIALLY DEFERRED ;
Sad day, but right after that I prepared to run the second step. That time I
checked the generated SQL with
sqlmigrate command and discovered it will
do the same thing again.
To avoid another failure, I did only a
Works great, but Django could do better handling these migrations.
from django.db import migrations , models
class Migration ( migrations . Migration ):
atomic = False
dependencies = [
( 'core' , '0137_auto_20200227_1304' ),
operations = [
migrations . SeparateDatabaseAndState (
state_operations = [
migrations . RenameField (
model_name = 'book' , old_name = 'author' , new_name = 'creator' ,
database_operations = ,
After that, I checked Django tickets and didn't found anything related. Created
a ticket and implemented two pull requests to fix both steps:
AlterField with db_column addition should be a noop and RenameField with db_column should be a noop. They were merged and released with Django 3.1.1 after long PR conversations.
Django is a huge codebase and even a minor change like that took me some days,
changing the wrong things in the different wrong ways. I learned a lot and was
able to fix another migrations issue:
AlterOrderWithRespectTo() with ForeignKey crash when _order is included in Index().
Right after these fixes, I upgraded our Django and hit a recent regression:
App with default_app_config and without apps.py or with an empty apps.py crashes.. It was a quick fix, but lots of tests written.
When our new intern started exploring Django querysets, he had an issue with queryset
in_bulk operation, because of incomplete docs and it generated a new ticket and quick fix: Queryset in_bulk docs don't explicit field_name as kwarg only.