Как удалить файл модели 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) с первого сервера на второй, таким образом, с этого момента запросы будут направляться на новый сервер.