Django启动代码放在哪里?

时间:2010-05-06 13:18:47

标签: python django django-middleware

我希望在服务器启动(开发和生产)上执行这些代码行:

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

将其放入settings.py不起作用,因为它需要已加载设置。

将它们置于视图中并从外部访问该视图也不起作用,因为有些中间件使用数据库而这些中间件将失败并且不允许我访问视图。

将它们置于中间件中会起作用,但每次访问我的应用程序时都会调用它。一个可能的解决方案可能是创建一个完成所有工作的中间件,然后从MIDDLEWARE_CLASSES中删除它,这样它就不再被调用了。如果没有太多的猴子补丁,我可以这样做吗?

6 个答案:

答案 0 :(得分:55)

编写在__init__中执行此操作的中间件,然后从django.core.exceptions.MiddlewareNotUsed中提升__init__,django将为所有请求删除它:)。顺便提一下,__init__会在第一次请求时调用,因此不会阻止第一个用户。

有关于添加启动信号的讨论,但很快就无法使用(例如,一个主要问题是应该发送此信号)

相关票证:https://code.djangoproject.com/ticket/13024

更新: Django 1.7包括对此的支持。 (Documentation,由票证链接)

答案 1 :(得分: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()

答案 2 :(得分:3)

您可以创建自定义命令并在handle函数中编写代码。详情请https://docs.djangoproject.com/en/dev/howto/custom-management-commands/

然后,您可以创建一个运行django服务器的启动脚本,然后执行新的自定义命令。

答案 3 :(得分:1)

如果您使用mod_wsgi,可以将其放入wsgi启动应用程序

答案 4 :(得分:0)

以下是我如何解决Django丢失的启动信号: https://github.com/lsaffre/djangosite/blob/master/djangosite/models.py 在那里调用的代码特定于我的djangosite项目,但通过编写一个特殊的应用程序(基于Ross McFarland的想法)来调用它的技巧应该适用于其他环境。 LUC

答案 5 :(得分:0)

在Django 1.7+中,如果要运行启动代码,

1。避免在迁移,makemigrations,shell会话等环境中运行它。

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