Django启动代码放在哪里?

Att*_* O. 50 python django django-middleware

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

from django.core import management
management.call_command('syncdb', interactive=False)
Run Code Online (Sandbox Code Playgroud)

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

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

将它们放在中间件中会起作用,但每次访问我的应用程序时都会调用它.一个可能的解决方案可能是创建一个中间件来完成所有工作,然后将其自身移除,MIDDLEWARE_CLASSES因此不再调用它.如果没有太多的猴子补丁,我可以这样做吗?

Kil*_*nDS 55

编写执行此操作的中间件,__init__然后django.core.exceptions.MiddlewareNotUsed从中获取__init__,django将删除所有请求:).__init__在启动时调用,而不是在第一个请求时调用,因此它不会阻止您的第一个用户.

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

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

更新: Django 1.7包括对此的支持.(文件,由机票链接)

  • 根据http://stackoverflow.com/questions/6791911/execute-code-when-django-starts-once-only,这可能会有问题.建议将启动功能放在urls.py中 (2认同)
  • 中间件和urls.py都不运行管理命令的启动代码.有更好的选择吗? (2认同)
  • @krizajB:请注意,这个答案是用django 1.0或1.1编写的,目前有更好的解决方案,也许这个解决方案在django 1.4中甚至不再有效.我会用更新的技术更新答案,但我最近没有做过很多django开发,所以如果有人知道更好的现代技术,请随意添加它. (2认同)
  • 这似乎不适用于python 1.4 ...任何建议/解决方法? (2认同)

Jos*_*ani 11

在 Django 1.7+ 中,如果您想运行启动代码,并且,

1. 避免在 migrate、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()
Run Code Online (Sandbox Code Playgroud)

文件:myapp/__init__.py

default_app_config = 'myapp.apps.MyAppConfig'
Run Code Online (Sandbox Code Playgroud)

这篇文章使用了 @Pykler 和 @bdoering 的建议