Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use apps.get_model() when creating a data migration?

As per the django docs when creating django migrations we should use apps.get_model() rather than importing the models and using them.

Why does a data migration have to use the historical version of a model rather than the latest one?(The historical versions of the model will not be in use anyways right?)

like image 759
user3282666 Avatar asked Jun 11 '16 15:06

user3282666


People also ask

What is the difference between Makemigrations and migrate in Django?

migrate , which is responsible for applying and unapplying migrations. makemigrations , which is responsible for creating new migrations based on the changes you have made to your models.

How do Django migration squash?

In Django's migrations code, there's a squashmigrations command which: "Squashes the migrations for app_label up to and including migration_name down into fewer migrations, if possible." So, if you want to squash, say, the first 5 migrations, this will help.


2 Answers

It uses the historical versions of the model so that it won't have problems trying to access fields that may no longer exist in the code base when you run your migrations against another database.

If you removed some field from your model and then wanted to run your migrations on some new database, and you were importing your models directly, you can expect your migrations would complain trying to use a field that doesn't exist. When using apps.get_model(...) Django will try to be smart about it and use the definitions of migrations.AddField(...) from your migrations files to give you the correct version of your model at that point in time.

This is also why Django says to be careful about using custom Model/Model Manager methods in your data migrations because I don't believe they can recreate these methods from the migrations history, or the behaviour can change over time and your migrations wouldn't be consistent.

like image 50
A. J. Parr Avatar answered Sep 27 '22 23:09

A. J. Parr


Consider this model:

class A(models.Model):
    field1 = models.PositiveIntegerField()
    field2 = models.PositiveIntegerField()

Your migration history knows about these two fields and any further migration will consider this model state and will make changes to this model state.

Now suppose, you remove field1 and your model becomes:

class A(models.Model):
    field2 = models.PositiveIntegerField()

And in the migration, you try to use field1, django should know that field1 existed. Hence when we use apps.get_model(), it helps django use the previous migrations history and infer about field1. Otherwise you will get an error.

like image 39
rohanagarwal Avatar answered Sep 27 '22 22:09

rohanagarwal