Django 启动代码放在哪里?

发布于 2024-08-31 09:05:36 字数 402 浏览 4 评论 0原文

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

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

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

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

将它们放入中间件中是可行的,但是每次访问我的应用程序时都会调用它。一个可能的解决方案可能是创建一个中间件来完成所有工作,然后将其自身从 MIDDLEWARE_CLASSES 中删除,这样就不再调用它了。我可以在不进行太多猴子修补的情况下做到这一点吗?

I'd like to have these lines of code executed on server startup (both development and production):

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

Putting it in settings.py doesn't work, as it requires the settings to be loaded already.

Putting them in a view and accessing that view externally doesn't work either, as there are some middlewares that use the database and those will fail and not let me access the view.

Putting them in a middleware would work, but that would get called each time my app is accessed. An possible solution might be to create a middleware that does all the job and then removes itself from MIDDLEWARE_CLASSES so it's not called anymore. Can I do that without too much monkey-patching?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

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

有人讨论添加启动信号,但这不会很快可用(例如,一个主要问题是何时应发送此信号)

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

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

Write middleware that does this in __init__ and afterwards raise django.core.exceptions.MiddlewareNotUsed from the __init__, django will remove it for all requests :). __init__ is called at startup by the way, not at the first request, so it won't block your first user.

There is talk about adding a startup signal, but that won't be available soon (a major problem for example is when this signal should be sent)

Related Ticket: https://code.djangoproject.com/ticket/13024

Update: Django 1.7 includes support for this. (Documentation, as linked by the ticket)

拥抱我好吗 2024-09-07 09:05:36

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

1. 避免在 migrate、makemigrations、shell 会话中运行它,...

2. 避免运行它两次或更多次

解决方案是:

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

In Django 1.7+ if you want to run a startup code and,

1. Avoid running it in migrate, makemigrations, shell sessions, ...

2. Avoid running it twice or more

A solution would be:

file: 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()

file: myapp/__init__.py

default_app_config = 'myapp.apps.MyAppConfig'

This post is using suggestions from @Pykler and @bdoering

沧笙踏歌 2024-09-07 09:05:36

如果您同时使用 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()

If you were using Apache/mod_wsgi for both, use the WSGI script file described in:

http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

Add what you need after language translations are activated.

Thus:

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()
安穩 2024-09-07 09:05:36

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

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

You can create a custom command and write your code in the handle function. details here https://docs.djangoproject.com/en/dev/howto/custom-management-commands/

Then you can create a startup script that runs the django server then executes your new custom command.

你在我安 2024-09-07 09:05:36

如果您使用 mod_wsgi 您可以将其放入 wsgi start 应用程序中

If you are using mod_wsgi you can put it in the wsgi start app

娇妻 2024-09-07 09:05:36

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

Here is how I work around the missing startup signal for Django:
https://github.com/lsaffre/djangosite/blob/master/djangosite/models.py
The code that is being called there is specific to my djangosite project, but the trick to get it called by writing a special app (based on an idea by Ross McFarland) should work for other environments.
Luc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文