我正在编写一个Django中间件类,我想在启动时只执行一次,以初始化其他一些任意代码。我遵循了sdolan在这里发布的非常好的解决方案,但是“Hello”消息输出到终端两次。如。
from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
class StartupMiddleware(object):
def __init__(self):
print "Hello world"
raise MiddlewareNotUsed('Startup complete')
在我的Django设置文件中,我已经在MIDDLEWARE_CLASSES列表中包含了这个类。
但是当我使用runserver运行Django并请求一个页面时,我进入了终端
Django version 1.3, using settings 'config.server'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Hello world
[22/Jul/2011 15:54:36] "GET / HTTP/1.1" 200 698
Hello world
[22/Jul/2011 15:54:36] "GET /static/css/base.css HTTP/1.1" 200 0
知道为什么"Hello world"打印了两次吗?谢谢。
在我的例子中,我使用Django来托管一个站点,并使用Heroku。我在Heroku使用1个dyno(就像1个容器),这个dyno创建了两个工人。
我想在上面运行一个不和机器人。我尝试了这个页面上的所有方法,都是无效的。
因为它是一个部署,所以不应该使用manage.py。相反,它使用gunicorn,我不知道如何添加-noreload参数。
每个worker运行一次wsgi.py,因此每个代码将运行两次。两个工人的当地环境是一样的。
但我注意到一件事,每次Heroku部署,它使用相同的pid工作。所以我只是
if not sys.argv[1] in ["makemigrations", "migrate"]: # Prevent execute in some manage command
if os.getpid() == 1: # You should check which pid Heroku will use and choose one.
code_I_want_excute_once_only()
我不确定pid在未来是否会改变,希望它永远是一样的。如果你有更好的方法来检查是哪个工人,请告诉我。
在我的例子中,我使用Django来托管一个站点,并使用Heroku。我在Heroku使用1个dyno(就像1个容器),这个dyno创建了两个工人。
我想在上面运行一个不和机器人。我尝试了这个页面上的所有方法,都是无效的。
因为它是一个部署,所以不应该使用manage.py。相反,它使用gunicorn,我不知道如何添加-noreload参数。
每个worker运行一次wsgi.py,因此每个代码将运行两次。两个工人的当地环境是一样的。
但我注意到一件事,每次Heroku部署,它使用相同的pid工作。所以我只是
if not sys.argv[1] in ["makemigrations", "migrate"]: # Prevent execute in some manage command
if os.getpid() == 1: # You should check which pid Heroku will use and choose one.
code_I_want_excute_once_only()
我不确定pid在未来是否会改变,希望它永远是一样的。如果你有更好的方法来检查是哪个工人,请告诉我。
更新:Django 1.7现在有一个钩子
: myapp / app . py文件
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = "My Application"
def ready(self):
pass # startup code here
文件:myapp / __init__ . py
default_app_config = 'myapp.apps.MyAppConfig'
对于Django < 1.7
第一个答案似乎不再工作了,urls.py在第一次请求时加载。
最近起作用的是将启动代码放在任何一个INSTALLED_APPS init.py中,例如myapp/__init__.py
def startup():
pass # load a big thing
startup()
当使用。/manage.py runserver…这将被执行两次,但这是因为runserver有一些技巧来首先验证模型等等。正常部署,甚至当runserver自动重新加载时,这只执行一次。