How to delete a Django model file without restarting the server and trigger migrations?

I'm working on a Django application where I need to programmatically delete a model file (e.g., my_app/models/my_model.py) and then run migrations, all without restarting the server. However, after deleting the file and running makemigrations, Django doesn't recognize any changes and doesn't generate a migration to remove the model.

I've tried reloading the modules using importlib.reload(), but that hasn't resolved the issue. The system only detects the changes after I restart the server.

Does Django or Python keep references to the model elsewhere, preventing the changes from being registered immediately? Is there a way to resolve this without having to restart the server?

    file_path = 'my_app/models/my_model.py'
    if os.path.exists(file_path):
        os.remove(file_path)

    #Update __init__.py
    init_file_path = 'my_app/models/__init__.py'
    with open(init_file_path, 'r') as file:
        lines = file.readlines()

    with open(init_file_path, 'w') as file:
        for line in lines:
            if 'my_model' not in line:
                file.write(line)


    module_name = 'my_app.models'
        if module_name in sys.modules:
            del sys.modules[module_name]

    module = importlib.import_module(module_name)
    importlib.reload(module)

    call_command('makemigrations', 'concrete_models')
    call_command('migrate', 'concrete_models')

I'm working on a Django application where I need to programmatically delete a model file (e.g., my_app/models/my_model.py) and then run migrations, all without restarting the server.

Even if that would somehow work, I would strongly advise not to do that. It creates all sorts of side-effects. Dynamically loading modules will have all sorts of caveats, for example if you load:

from myapp.models import MyModel

then the idea is that even if the module changes, you have a reference to the MyModel class object. At best, if you would change the MyModel class in the myapp.models module, it will print tracebacks with the new lines, and thus generate a lot of noise.

In fact sometimes this behavior is wanted w.r.t. monkey patching [wiki] where you for example get a reference to the old class, then for example "inject" a new class in the module, but still have a reference to the old file.

When updating a server, I would advise to work with a second Django/gunicorn app that you thus start with the new module. Then you set that up running, and finally you change the "routing" (for example through nginx) from the first server to the second, that way from now on, requests will be routed to the new server.

Back to Top