Django启动代码放在哪里?

56 投票
6 回答
28105 浏览
提问于 2025-04-15 22:25

我想在服务器启动时执行这些代码(无论是开发环境还是生产环境):

from django.core import management
management.call_command('syncdb', interactive=False)

把它放在 settings.py 里不行,因为那样需要先加载设置。

把它放在一个视图里,然后外部访问那个视图也不行,因为有一些中间件会用到数据库,这样就会出错,导致我无法访问这个视图。

把它放在中间件里是可行的,但这样每次访问我的应用时都会被调用。一个可能的解决办法是创建一个中间件,完成所有工作后再把自己从 MIDDLEWARE_CLASSES 中移除,这样就不会再被调用了。我能做到这一点而不需要太多复杂的修改吗?

6 个回答

4

如果你在使用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()
11

在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的建议。

61

写一个中间件,在__init__里做一些事情,然后在__init__中抛出django.core.exceptions.MiddlewareNotUsed这个错误,Django会在所有请求中把它去掉。顺便说一下,__init__是在启动时调用的,而不是在第一次请求时,所以不会影响到第一个用户。

现在有讨论要添加一个启动信号,但这个功能不会很快推出(一个主要的问题是这个信号应该在什么时候发送)。

相关链接:https://code.djangoproject.com/ticket/13024

更新: Django 1.7已经支持这个功能了。(文档,在这个链接中可以找到)

撰写回答