I have made multiple changes to an existing django model (added new foreign key relation, etc). Before creating and applying these changes with manage.py makemigrations / migrate, I adapted the corresponding admin module's ModelAdmin for that app to reflect these unapplied changes.
Running makemigrations now fails with "ProgrammingError: {new_field} does not exist". I figure this happens because when makemigrations runs system checks, the ModelAdmins in admin.py are registered (executing queries on non-existant models that I try to create with the migrations).
Question: Is there any straight-forward way to exclude the ModelAdmins from being registered when running manage.py makemigrations / migrate without disabling system checks in total (see Django migration - disabel system checks)?
I can solve the problem by deleting my admin.py modules when running makemigrations / migrate and recreating them afterwards. There is really no need to check the admin modules when migrating, but I guess this will happen when registering ModelAdmins on the module-level of admin.py (as in the examples in the django admin documentation). I do not use a custom AdminSite.
On more general terms: is there any straight-forward way to exclude specific top-level module code from being executed when running a specific manage.py command like makemigrations or migrate?
I figured out a reasonable way to do this.
Since I was so desperately searching for a django-native way to check for the current command, I did not think of simply evaluating the command line arguments like normal to do this.
When calling makemigrations or migrate from the command line, I can get the name of the command with sys.argv[1]
. This should work in any top-level code that is automatically executed when django runs system checks.
The registering of ModelAdmins is caused through django.contrib.admin.autodiscover()
, which is automatically called when using the default AdminConfig
(i.e. when django.contrib.admin
is included in the INSTALLED_APPS
setting). We can use django.contrib.admin.apps.SimpleAdminConfig
in the setting instead, so that autodiscover()
will not be called automatically (see django admin docs).
I changed the corresponding part in my settings.py
from
INSTALLED_APPS = [
...
"django.contrib.admin",
...
]
to
MIGRATION_COMMAND = sys.argv[1] in ('makemigrations', 'migrate')
INSTALLED_APPS = [
...
"django.contrib.admin.apps.SimpleAdminConfig" if MIGRATION_COMMAND else "django.contrib.admin",
...
]
This way, all the admin.py
modules of my apps will be ignored when running makemigrations / migrate.
I can now also use the custom MIGRATION_COMMAND
setting anywhere else if I need to.