Как удалить файл модели Django без перезапуска сервера и запуска миграций?

Я работаю над приложением Django, в котором мне нужно программно удалить файл модели (например, my_app/models/my_model.py), а затем запустить миграции, не перезапуская сервер. Однако после удаления файла и запуска makemigrations Django не распознает никаких изменений и не генерирует миграцию для удаления модели.

Я пробовал перезагружать модули с помощью importlib.reload(), но это не решило проблему. Система обнаруживает изменения только после перезапуска сервера.

Сохраняет ли Django или Python ссылки на модель в другом месте, не позволяя немедленно зарегистрировать изменения? Есть ли способ решить эту проблему, не перезапуская сервер?

    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')

Я работаю над приложением Django, где мне нужно программно удалить файл модели (например, my_app/models/my_model.py), а затем запустить миграции, и все это без перезапуска сервера.

Даже если бы это каким-то образом сработало, я бы настоятельно не советовал этого делать. Это создает всевозможные побочные эффекты. Динамическая загрузка модулей будет иметь всевозможные оговорки, например, если вы загрузите:

from myapp.models import MyModel

то идея заключается в том, что даже если модуль изменится, у вас останется ссылка на объект класса MyModel. В лучшем случае, если вы измените класс MyModel в модуле myapp.models, он напечатает трассировки с новыми строками и, таким образом, создаст много шума.

На самом деле иногда такое поведение нужно для обезьяньих патчей [wiki], где вы, например, получаете ссылку на старый класс, затем, например, "инжектируете" новый класс в модуль, но при этом сохраняете ссылку на старый файл.

При обновлении сервера я бы посоветовал работать со вторым приложением Django/gunicorn, которое вы таким образом запускаете с новым модулем. Затем вы запускаете его, и, наконец, меняете "маршрутизацию" (например, через nginx) с первого сервера на второй, таким образом, с этого момента запросы будут направляться на новый сервер.

Вернуться на верх