问题
I am asking this question because I ran into this django.db.utils.IntegrityError: null value in column “lft” violates not-null constraint when I was using django-hordak which uses MPPT models.
The solution provided is hacky as it violates the common practice but it works.
THE BASICS
In django when writing custom migrations for example when creating baseline data.
def forward_func(apps_registry, schema_editor):
Model = apps_registry.get_model('app_name', 'ModelName')
Model.objects.create(**{'field_1': 'field_1', 'field_2': 'field_2')
# Do whatever you want with my Model
In my situation django-hordak with the account model. That .objects.create(**data)
raises theIntegrityError on the DB as specified above.
Proposed solution
The proposed solution is to import the model directly.
def forward_func(apps_registry, schema_editor):
# Model = apps_registry.get_model('app_name', 'ModelName')
# lets forget about importing the standard way because it will raise integrity error.
from app_name.models import ModelName as Model
# Now we can proceed to deal with our model without Integrity Error.
Model.objects.create(**data)
This leaves me scared of possible undesirable side effects of importing models directly in migrations files.
As there must be very good reasons why the model is not imported that way in the migration files.
I am not looking for the reason why MPTT models fail when imported the standard way as that question has an answer here. .
I want to understand particularly the logic behind importing models using app_registry.get_model in migration files.
回答1:
that is a very good question, as there is in deed a very big difference.
If you import a model, you will get whatever is currently defined in your model code. But what happens if you want to remove a model? How do you make sure your migration will still work?
That's why there is apps.get_model. It will give you a "virtual" Model based on state defined by the previous migrations. Note that this is not the same as the Model in your code. It does not have any of the custom functions and behaviors you implemented unless they are part of the ORM API. In other words mostly fields and meta options like ordering and co.
Please also note that the correct signature is apps not app_registry. It should not be confused with the app registry in django.apps.apps. It has a get_model method too. This one however will return the model in your current code.
I know it can be all a bit confusing at first (and even later). I would suggest following a simple rule. Do not import any of your own code into a migration. Backport behavior into the migration, if you must.
I hope that distinction helps you a bit. Please leave me a comment if you have further questions. I am happy to extend my answer.
Best -Joe
来源:https://stackoverflow.com/questions/59142674/whats-the-logic-of-importing-models-as-app-registry-get-modelapp-name-mode