django 服务器启动时如何启动后台线程?

Jin*_*n.J 4 python django python-3.x mqtt

TL;DR在我的 django 项目中,我在哪里放置我的“启动线程”代码以在 django 服务器启动后立即运行线程?

首先祝大家新年快乐!这是一个新手的问​​题,所以它可能看起来很愚蠢。提前感谢您的耐心和帮助!

背景资料
最近我在写一个接收MQTT消息的MQTT转发程序。我希望用户设置一些规则来处理要转发的消息,所以我选择了 django 来构建 Web 服务器。用户可以在网页上自行编辑规则。
对于 MQTT 客户端,无论用户是否打开网页,我都需要有一个线程来接收 MQTT 消息,因此我无法在view.py 中编写它。如果我编写一个 shell 来分别启动 django 服务器和我的脚本,我不确定如何将用户设置从 django 服务器传递到我的 mqtt 客户端脚本。

问题
1. 有没有办法在我输入后立即启动后台线程python manage.py runserver
2.用户设置之一是MQTT服务器主机,所以一旦用户在网页上更改了这个条目,后台MQTT客户端应该重新启动并连接到新主机。有什么方法可以实现吗?

我做了一些研究和一些可能的解决方案,我发现是django-background-tasksCelery,但我不知道这些是正确的方式,我认为这个问题是太小,无法导入另一个沉重的模块来处理。请给我一些建议!如果您有任何不清楚的地方,请随时问我!
再次感谢你!

Chr*_*ris 6

我觉得你可以做的就是启动线程在ready()你的方法AppConfigapps.py

这里有一个简单的例子

# apps.py
from django.apps import AppConfig
from threading import Thread

class TestThread(Thread):

    def run(self):
        print('Thread running')



class StackConfig(AppConfig):
    name = 'stack'

    def ready(self):
        TestThread().start()
Run Code Online (Sandbox Code Playgroud)

如果您需要应用程序其他部分的代码,请注意您不能在模块级别导入它,即如果您在 apps.py 中尝试类似的操作

#apps.py
from . models import Code
Run Code Online (Sandbox Code Playgroud)

将引发异常:

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet
Run Code Online (Sandbox Code Playgroud)

为了避免这种情况,您需要在您的ready()方法中进行导入:

#apps.py
class StackConfig(AppConfig):
        name = 'stack'

        def ready(self):
            from stack.models import Code
            TestThread().start()
Run Code Online (Sandbox Code Playgroud)

这在docs 中有描述

为了使所有这些工作,请确保您在 settings.INSTALLED_APPS 中启动您的应用程序

'stack.apps.StackConfig',
Run Code Online (Sandbox Code Playgroud)