Я хочу запустить некоторый код при запуске моего сервера Django, чтобы очистить предыдущий конец сервера. Как я могу запустить некоторый код один и только один раз при запуске, прежде чем сервер обработает какие-либо запросы. Мне нужно получить доступ к базе данных в это время.
Я прочитал в Интернете пару вещей, которые кажутся немного устаревшими и не гарантируют, что они будут запускаться только один раз.
Я рассмотрел предложенный ответ, изучив функцию ready
. Кажется, это работает, но документально подтверждено, что вам не следует обращаться к этой базе данных (https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready).
Есть много предложений в Выполнять код при запуске Django только ОДИН РАЗ?, но поскольку этому посту несколько лет, я подумал, что могут быть какие-то дополнительные решения.
Это выглядит многообещающе
from django.dispatch import receiver
from django.db.backends.signals import connection_created
@receiver(connection_created)
def my_receiver(connection, **kwargs):
with connection.cursor() as cursor:
# do something to the database
connection_created.disconnect(my_receiver)
Есть еще мысли?
Я хочу, чтобы он работал немного более автоматически при запуске сервера.
Это часто делается с помощью метода .ready() [Django-doc] любого из классов AppConfig [Django-doc] установленного приложения. Итак, если у вас есть приложение app_name
, вы можете работать с:
# app_name/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
# …
def ready(self):
# my management command
# …
Это запустится после загрузки всех моделей INSTALLED_APPS
, так что вы сможете выполнять команды управления. Это также часто используется для подключения сигналов к моделям.
Спасибо. Дополнительную информацию можно найти здесь: stackoverflow.com/questions/33814615/…, чтобы предотвратить повторный запуск. Я использовал `if os.environ.get('RUN_MAIN'):`
@PeterKronenberg: ну, Django перезагружается только в режиме разработки. Возможно, что если вы используете, например, Gunicorn, он порождает несколько процессов, но, таким образом, один раз для каждого процесса.
Будет ли эта проверка работать и в других средах? Я хочу убедиться, что он запускается только один раз, прежде чем принимать какие-либо запросы.
RUN_MAIN
является AFAIK специфичным для Django runserver
, он не будет работать с другими методами выполнения. Ваша проверка будет зависеть от того, как вы развертываете приложение. Например, для gunicorn
посмотрите этот ответ.
Я обновил свой вопрос
Если он не обязательно должен быть в начале сервера, но может быть запущен до запуска сервера, вы можете просто создать пользовательскую команду управления и запустить ее перед запуском сервера.