1

我试图在命令后立即调用函数,python manage.py runserver它可以是简单的打印。我读了一些东西,发现了一些非常有趣的主题,def ready(self)比如 在 Django 仅启动 ONCE 时覆盖 AppConfig.ready() 或执行代码?我按照说明进行操作,但对于 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
.
.
.

但是没有连接在此处输入图像描述

4

3 回答 3

2

编辑:

我仍然不确定您要达到的目标,并且评论者强调了一些重要的问题。首先,这个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.pylikedjango-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模块或单个应用程序的 AppConfigready()方法。

如果您想构建独立于 Django 并在后台持续运行的东西,那么正如@bruno-desthuilliers 指出的那样,您需要构建一个单独的进程作为 cron 作业或使用 celery 甚至 django-carrot 如果您愿意,尽管后者仍与应用程序启动相关联,但可以作为单独的工作人员工作(我认为)。Django-carrot 只有非常简单的小工作功能。

如果这没有任何帮助,我很抱歉,我可以用提供的信息做最好的事情。


ready()当我想在我的应用程序 AppConfig的方法中运行某些东西时,我遇到了类似的问题。对我来说,这是我的应用程序安装在我的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

所以

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在应用程序加载后将 a 放置在项目模块中

IE

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

希望有帮助

于 2019-01-02T14:02:24.903 回答
0

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

覆盖AppConfig.ready()用于子类化AppConfig并将其添加到应用程序注册表时。从您的问题中不清楚您是否遵循了该部分。您可以仔细检查您是否按照此处的说明进行操作,以确保您已正确完成操作。

于 2019-01-02T13:57:35.067 回答
0

我的解决方案有点不同,我愿意接受所有人的建议。灵感来自@alfandango's answer to use wsgi.py to run the custom code one time and some other references类似于当前问题,指出将代码放在urls.py中将执行一次代码,但仅在第一次命中任何网址出现。请注意,该解决方案仅在以下情况下才有帮助/建议:

  1. 您想在系统首次运行时运行数据库命令/访问数据库
  2. 你只有一名工人。该代码还将为多个工作人员运行,但将为每个工作人员调用一次
  3. 如您所见,您可以将代码的执行延迟 1 秒(或更短)。

解决方案: STEP1:将以下代码添加到根 urls.py :

#normal URL.py invocation
urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^somepaths/', include((some_url, 'some_url'), namespace="some_urls")),
]

#define or import your function
def run_after_system_start():
    pass

#now run the functions
run_after_system_start()

STEP2:在 wsgi.py 中运行 wget 调用 url.py #regular code for wsgi.py import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'applications.settings')

import os
application = get_wsgi_application()


#below code hits itself(http://0.0.0.0) at some url to just invoke url.py and run the code once. The option for Wget are to enable no output or error is printed. It retries only once with a timeout of 1 second. Also the HIT type is of HTTP POST

try:
    os.system('wget -T 1 -q -o /dev/null -O "/dev/null" --tries=1 --post-data "" http://0.0.0.0/someurl')
except Exception as e:
    pass

其他参考:

  1. Wget 没有错误信息/输出
于 2021-09-24T22:27:01.150 回答