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?)
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.