原文出处:
Stack Overflow
Execute code when Django starts ONCE only?
在我的Django settings.py文件里,我已经把这个中间件类加入到了MIDDLEWARE_CLASSES列表中。
但当我使用runserver命令启动Django并发起了一次页面请求,我在终端里面看到了这样的信息,“Hello world”打印了两遍:
该回答被选为最佳答案,获得61个赞。
你这样做的方式是不对的!
不要使用中间件去做只执行一次的操作。
你可以将执行代码放到项目顶层的urls.py中,这个模块会被加载而且只执行一次(注意:从Django1.9版本开始这个是正确的,但之前的版本不行----By Django的那些事儿)。
urls.py
该回答获得最高的151个赞。
从Django1.7版本开始,为该问题提供了一个解决方案。
文件:myapp/apps.py
文件:myapp/__init__.py
2、Django1.7以前的版本解决方案:
该问题的第一个回答似乎不起作用,urls.py是在第一次请求后加载的。
当执行./manage.py runserver ... 命令时,上述代码会被执行两次,这是因为runserver命令会在启动前做一些小动作,例如检查模型等。正常的部署环境或者是runserver 命令重新加载,都只会执行一次。
首先,就像回答1说的那样,这个问题不要使用中间件来解决(虽然可以解决,但不是好的方案)。
MiddlewareNotUsed这个异常类是用来做什么的?
有时候我们会遇到这样的需求,在DEBUG=True时,我们需要加载中间件A,让它工作。但DEBUG=false时,我们就不希望中间件A工作了。
这个需要在运行时来决定哪个中间件是否可用是十分必要的,这种情况下你的自定义中间件__init__方法可以 raisedjango.core.exceptions.MiddlewareNotUsed,抛出MiddlewareNotUsed异常,django将会禁用该中间件。
使用应用配置类的AppConfig.ready()方法,我个人觉得是很好的方案,推荐大家使用。
至于终端里打印了两遍信息的问题,可以使用--noreload来解决。
python manage.py runserver --noreload
但这样做的话,一旦你动态的修改了项目源码,runserver是不会自动重新加载的,你需要自己重启server的。