I’m planning to rename several models in an existing Django project where there are many other models that have foreign key relationships to the models I would like to rename. I’m fairly certain this will require multiple migrations, but I’m not sure of the exact procedure.
Let’s say I start out with the following models within a Django app called myapp
:
class Foo(models.Model): name = models.CharField(unique=True, max_length=32) description = models.TextField(null=True, blank=True) class AnotherModel(models.Model): foo = models.ForeignKey(Foo) is_awesome = models.BooleanField() class YetAnotherModel(models.Model): foo = models.ForeignKey(Foo) is_ridonkulous = models.BooleanField()
I want to rename the Foo
model because the name doesn’t really make sense and is causing confusion in the code, and Bar
would make for a much clearer name.
From what I have read in the Django development documentation, I’m assuming the following migration strategy:
Step 1
Modify models.py
:
class Bar(models.Model): # <-- changed model name name = models.CharField(unique=True, max_length=32) description = models.TextField(null=True, blank=True) class AnotherModel(models.Model): foo = models.ForeignKey(Bar) # <-- changed relation, but not field name is_awesome = models.BooleanField() class YetAnotherModel(models.Model): foo = models.ForeignKey(Bar) # <-- changed relation, but not field name is_ridonkulous = models.BooleanField()
Note the AnotherModel
field name for foo
doesn’t change, but the relation is updated to the Bar
model. My reasoning is that I shouldn’t change too much at once and that if I changed this field name to bar
I would risk losing the data in that column.
Step 2
Create an empty migration:
python manage.py makemigrations --empty myapp
Step 3
Edit the Migration
class in the migration file created in step 2 to add the RenameModel
operation to the operations list:
class Migration(migrations.Migration): dependencies = [ ('myapp', '0001_initial'), ] operations = [ migrations.RenameModel('Foo', 'Bar') ]
Step 4
Apply the migration:
python manage.py migrate
Step 5
Edit the related field names in models.py
:
class Bar(models.Model): name = models.CharField(unique=True, max_length=32) description = models.TextField(null=True, blank=True) class AnotherModel(models.Model): bar = models.ForeignKey(Bar) # <-- changed field name is_awesome = models.BooleanField() class YetAnotherModel(models.Model): bar = models.ForeignKey(Bar) # <-- changed field name is_ridonkulous = models.BooleanField()
Step 6
Create another empty migration:
python manage.py makemigrations --empty myapp
Step 7
Edit the Migration
class in the migration file created in step 6 to add the RenameField
operation(s) for any related field names to the operations list:
class Migration(migrations.Migration): dependencies = [ ('myapp', '0002_rename_fields'), # <-- is this okay? ] operations = [ migrations.RenameField('AnotherModel', 'foo', 'bar'), migrations.RenameField('YetAnotherModel', 'foo', 'bar') ]
Step 8
Apply the 2nd migration:
python manage.py migrate
Aside from updating the rest of the code (views, forms, etc.) to reflect the new variable names, is this basically how the new migration functionality would work?
Also, this seems like a lot of steps. Can the migration operations be condensed in some way?
Thanks!
Advertisement
Answer
So when I tried this, it seems you can condense Step 3 – 7:
class Migration(migrations.Migration): dependencies = [ ('myapp', '0001_initial'), ] operations = [ migrations.RenameModel('Foo', 'Bar'), migrations.RenameField('AnotherModel', 'foo', 'bar'), migrations.RenameField('YetAnotherModel', 'foo', 'bar') ]
You may get some errors if you don’t update the names where it’s imported e.g. admin.py and even older migration files (!).
Update: As ceasaro mentions, newer versions of Django are usually able to detect and ask if a model is renamed. So try manage.py makemigrations
first and then check the migration file.