Django:只为`made.py runserver`执行代码,不为`Migrate`、`hel`等执行代码

人气:599 发布:2022-10-16 标签: python django server neural-network

问题描述

我们正在使用Django作为一个网站的后端,该网站提供各种内容,其中使用神经网络使用TensorFlow来回答某些请求。

为此,我们创建了AppConfig,并将此应用程序配置的加载添加到Django的settings.py中的INSTALLED_APPS。一旦初始化,此AppConfiger就会加载神经网络:

settings.py:

INSTALLED_APPS = [
...
    'bert_app.apps.BertAppConfig',
]

.../BERT_app/app.py:

class BertAppConfig(AppConfig):
    name = 'bert_app'
    if 'bert_app.apps.BertAppConfig' in settings.INSTALLED_APPS:
        predictor = BertPredictor() #loads the ANN.
现在,当它工作并做它应该做的事情时,ANN现在为通过运行的每个单独的命令加载。当然,我们希望在您调用manage.py runserver时执行它,但不希望它针对manage.py migratemanage.py help和所有其他命令运行。

我通常不确定这是否是为Django后端加载ANN的正确方式,那么有谁有任何提示如何正确地做到这一点呢?我可以想象,在启动时加载模型并不是最好的做法,我非常愿意听取有关如何正确执行此操作的建议。

然而,除了实际的模型加载之外,还有一些其他代码也需要几秒钟的时间,而且肯定应该在服务器启动时立即执行(因此manage.py runserver),但也不会在manage.py help上执行(因为也需要几秒钟),那么有什么快速修复方法让Django只在runserver上执行它,而不是在它的其他命令上执行吗?

推荐答案

我遇到了类似的问题,通过检查argv解决了它。

class SomeAppConfig(AppConfig):

    def ready(self, *args, **kwargs):
        is_manage_py = any(arg.casefold().endswith("manage.py") for arg in sys.argv)
        is_runserver = any(arg.casefold() == "runserver" for arg in sys.argv)

        if (is_manage_py and is_runserver) or (not is_manage_py):
            init_your_thing_here()
现在更接近if not is_manage_py部分:在生产中,您使用uwsgi/uvicorn/...运行您的Web服务器,它仍然是一个Web服务器,只是它不使用运行。最有可能的是,它是您运行时唯一不需要manage.py

的东西

使用AppConfig.ready()-它是为它设计的:

子类可以重写此方法以执行初始化任务,如注册信号。一旦注册表填满,就会立即调用它。-[django documentation]

若要取回AppConfig,请使用:

from django.apps import apps
apps.get_app_config(app_name)
# apps.get_app_configs()  # all

505