我有一些django代码,当我的应用程序加载到开发服务器或作为wsgi worker时,需要运行一次。此代码也需要写入数据库。在我的特定情况下,我不需要运行许多管理命令(如collectstatic或createsuperuser等)的代码。
此SO问题"Where to put Django startups code?"建议使用AppConfig.ready作为启动代码。
但是,docs for the ready function明确警告不要与数据库进行交互:
尽管您可以如上所述访问模型类,但要避免在ready()实现中与数据库进行交互。这包括执行查询的模型方法(save(),delete(),manager方法等),以及通过django.db.connection进行的原始SQL查询。您的ready()方法将在每个管理命令启动期间运行。例如,即使测试数据库配置与生产设置是分开的,manage.py测试仍将对您的生产数据库执行一些查询!
我是否应该在以后需要用于更新数据库的代码中使用一些启动钩子?
该代码将我的服务器注册为具有第三方服务的Webhook端点,并将所需的连接信息存储在数据库中。我仅注册Webhook(如果尚未配置)。
我们有一个类似的用例:如果服务器重新启动,则需要管理数据库信息,以免某些过程处于停顿状态。
我们解决此问题的方法是使用systemd脚本,该脚本在启动期间仅执行一次,该脚本调用一个脚本,该脚本在Django数据库中执行操作。
1)创建一个python脚本,它将执行所需的操作并更改数据库:
/djangoproject/boot_script.py
其中包含:
from djangoapp.models import XModel
python manage.py shell < boot_script.py
2)创建一个脚本,其中包含对Django的python脚本的调用:
/.../execute_boot_script.sh
其中包含:
cd /djangoproject
python manage.py shell < boot_script.py
3)为服务创建文件:
/etc/systemd/system/execute_boot_script.service
其中包含:
[Unit]
After=apache2.service
[Service]
Environment=ENVPATH=:/usr/local/... # ONLY IF YOU NEED TO SET SOME ENVIRONMENT VARIABLE
Type=oneshot
ExecStart=/.../execute_boot_script.sh
[Install]
WantedBy=multi-user.target
更多信息:https://linuxconfig.org/how-to-automatically-execute-shell-script-at-startup-boot-on-systemd-linux
此答案在linux中有效,但是通过在启动时启动已编程的任务也可以在Windows中轻松实现。