启动Django开发服务器后立即调用函数。 (Django / Python)

时间:2019-01-02 13:23:34

标签: python django function startup django-2.1

我正在尝试在命令python manage.py runserver之后立即调用函数,这可能是简单的打印。我读了一些东西,发现像def ready(self)这样的有趣话题 Overriding AppConfig.ready()Execute code when Django starts ONCE only?我按照说明进行操作,但对于django 2.1.3版本不起作用。我一次没有得到一次准备好的功能,而我又得到了AppRegistryNotReady exceptions一堆。我认为服务器启动后的调用功能很常见。它不会给您带来太多麻烦,但我仍然找不到合适的解决方案

更新

我尝试了另一种解决方案

我创建这样的中间件类:

import time


class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        while True:
            print("true")
            time.sleep(5)

    def __call__(self, request):

        response = self.get_response(request)

        return response

现在我得到正确的输出,如:

Performing system checks...

System check identified no issues (0 silenced).
January 03, 2019 - 14:10:55
Django version 2.1.3, using settings 'CMS.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
true
true
true
true
true
true
true
.
.
.

但没有连接enter image description here

2 个答案:

答案 0 :(得分:0)

您可以仅在manage.py末尾,在routes.py之类的支持文件中添加函数调用,依此类推。但!您表示希望在服务器准备好接收请求时调用该函数。

覆盖AppConfig.ready()适用于您将AppConfig子类化并将其添加到应用程序注册表中的情况。从您的问题尚不清楚您是否遵循了这一部分。您可以再次检查自己是否遵循了here的说明,以确保正确完成了该操作。

答案 1 :(得分:0)

编辑:

我仍然不确定您要达到的目标,评论者强调了一些重要的问题。首先,AppRegistryNotReady: Apps aren't loaded yet错误确实令人沮丧,我对此表示赞赏。我不确定您如何组织项目,因此无法提供确切的解决方案。这可能是组织文件以及从中导入应用程序的AppConfig类的方式。您是否在应用程序包级别__init__.py中放置了它或任何自定义函数或类,以便从那里导入?如果是这样,这似乎会使Django感到困惑,请参阅https://stackoverflow.com/a/34136825/2275482

第二:

  

我正试图在命令python manage.py runserver之后调用函数

我认为我们正在努力了解您要实现的目标以及您是否在将Django应用程序启动时与服务器启动时进行合并。评论者指出,Web服务器完全独立于Django。这是一个独立的过程。

即使与Django捆绑在一起的测试服务器也独立于Django应用。它只是为了方便而放置的简单开发服务器,但这不是必需的,也不应该在生产中使用。 Django的建立符合PEP 333。它可以在AFAIK上与任何与PEP 333兼容的WSGI Web服务器一起使用,无论是Apache和mod_wsgi,gunicorn还是uWSGI等。如果要相对于所使用的服务器执行代码,则需要检查一下服务器文档。

manage.py之类的

django-admin只是一个有助于开发的实用程序,请参见https://docs.djangoproject.com/en/2.1/ref/django-admin/。调用manage.py runserver时,您正在调用一个实用程序,该实用程序将加载您的应用程序并设置测试服务器。您可以在文件本身中看到执行的流程,正在导入的实用程序等等。该执行流程与使用生产服务器时的执行流程不同。

据我所知,生产服务器从根wsgi.py文件中加载django应用程序。它甚至不会看manage.py

因此,这又回到了您是否在服务器启动后尝试发布消息的情况,在这种情况下,该消息独立于Django还是当Django应用程序启动时?

如果您要在django应用程序启动,启动并加载到服务器后尝试打印内容,则有很多选择。如果确实愿意,您可以编辑并添加到manage.py中,但除此之外,我不会篡改Django的核心。当使用其他生产服务器时,这将完全被忽略。

如果要编辑无论使用什么服务器都将加载的入口点,则可以编辑项目的wsgi.py模块或单独的App AppConfig ready()方法。

如果您要构建独立于Django并在后台连续运行的东西,则正如@ bruno-desthuilliers指出的那样,您需要构建单独的进程,作为cron作业,或者使用celery或django-carrot希望这样做,尽管后者仍与应用程序启动相关联,但可以作为单独的工作人员工作(我认为)。 Django-carrot仅具有非常简单的功能,适用于小型工作。

很抱歉,如果没有任何帮助,我会尽力提供所提供的信息。


当我希望在我的应用程序AppConfig的ready()方法中运行某些内容时,我遇到了类似的问题。对我来说,这就是在INSTALLED_APPS设置变量中安装应用程序的方式。

通常,您会像这样注册您的应用程序:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'my_app',
]

但是,这将加载基本的AppConfig类来注册您的应用程序。如果您自定义和覆盖应用程序的AppConfig,以便可以声明自己的ready()方法,该方法将在实例化应用程序后立即执行,则需要直接在INSTALLED_APPS中引用覆盖的AppConfig

所以

INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'my_app.apps.MyAPPConfig', # MyAppConfig is the config class that inherits from AppConfig
    ]

或者,如果您不希望在通过AppConfig加载特定应用程序时执行此操作,则不要通过ready()方法加载,而是从字面上看,当项目加载到服务器中时,您可以在其中放置一个应用加载后,将项目wsgi.py模块

application = get_wsgi_application()
print('Hello World')

希望有帮助