Django启动代码放在哪里?
我想在服务器启动时执行这些代码(无论是开发环境还是生产环境):
from django.core import management
management.call_command('syncdb', interactive=False)
把它放在 settings.py
里不行,因为那样需要先加载设置。
把它放在一个视图里,然后外部访问那个视图也不行,因为有一些中间件会用到数据库,这样就会出错,导致我无法访问这个视图。
把它放在中间件里是可行的,但这样每次访问我的应用时都会被调用。一个可能的解决办法是创建一个中间件,完成所有工作后再把自己从 MIDDLEWARE_CLASSES
中移除,这样就不会再被调用了。我能做到这一点而不需要太多复杂的修改吗?
6 个回答
如果你在使用Apache和mod_wsgi这两个工具,可以参考下面的WSGI脚本文件:
http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html
在激活语言翻译功能后,添加你需要的内容。
所以:
import sys
sys.path.insert(0, '/usr/local/django/mysite')
import settings
import django.core.management
django.core.management.setup_environ(settings)
utility = django.core.management.ManagementUtility()
command = utility.fetch_command('runserver')
command.validate()
import django.conf
import django.utils
django.utils.translation.activate(django.conf.settings.LANGUAGE_CODE)
# Your line here.
django.core.management.call_command('syncdb', interactive=False)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
在Django 1.7及以上版本,如果你想在程序启动时运行一些代码,
1. 要避免在迁移数据库、创建迁移文件、命令行会话等情况下运行这些代码。
2. 要避免代码被运行两次或更多次。
一个解决方案是:
文件:myapp/apps.py
from django.apps import AppConfig
def startup():
# startup code goes here
class MyAppConfig(AppConfig):
name = 'myapp'
verbose_name = "My Application"
def ready(self):
import os
if os.environ.get('RUN_MAIN'):
startup()
文件:myapp/__init__.py
default_app_config = 'myapp.apps.MyAppConfig'
这篇文章参考了@Pykler和@bdoering的建议。
写一个中间件,在__init__
里做一些事情,然后在__init__
中抛出django.core.exceptions.MiddlewareNotUsed
这个错误,Django会在所有请求中把它去掉。顺便说一下,__init__
是在启动时调用的,而不是在第一次请求时,所以不会影响到第一个用户。
现在有讨论要添加一个启动信号,但这个功能不会很快推出(一个主要的问题是这个信号应该在什么时候发送)。
相关链接:https://code.djangoproject.com/ticket/13024
更新: Django 1.7已经支持这个功能了。(文档,在这个链接中可以找到)