已在manage.py设置DJANGO_SETTINGS_MODULE,为何Celery仍需重复配置?
DJANGO_SETTINGS_MODULE in Celery when it's already set in manage.py? 你的测试结果在python manage.py runserver这个场景下确实没问题,但这行看似重复的代码,其实是为了应对不通过manage.py启动Celery的各种场景,具体来说:
直接启动Celery Worker的情况
如果你直接用celery -A projectname worker这类命令启动Celery,而不是通过manage.py,那manage.py里的环境变量设置根本不会被执行。这时候Celery代码里的os.environ.setdefault就会发挥作用,确保Django配置模块的路径能被正确找到。setdefault是兜底,不是强制覆盖
别忘了这行代码用的是setdefault,而不是直接赋值。这个方法只会在环境变量不存在的时候才会设置它——如果变量已经存在(比如通过manage.py或者其他方式提前设置过),这行代码完全不会改动现有值,只是做个兜底保障而已。生产部署场景的必要性
在生产环境里,大家通常会用supervisor、systemd这类工具直接启动Celery Worker,不会绕manage.py。这时候如果没有Celery代码里的这个设置,Celery根本没法加载Django的配置,连数据库模型、Broker配置这些核心依赖都用不了,直接就报错了。
你可以自己测试一下:注释掉Celery里的设置,然后直接运行
$ celery -A projectname worker --loglevel=info
这时候你会发现Celery直接报错找不到Django配置,因为这时候manage.py的代码根本没跑,环境变量压根没被设置。
而你用runserver测试时,manage.py先一步设置了环境变量,Celery导入时setdefault发现变量已经存在,就啥也没做,所以看起来这行代码没用,但它其实是为各种非manage.py启动的场景做的必要保险。
内容的提问来源于stack exchange,提问作者Santhosh

