Django集成MQTT调用全局变量test报name 'test' is not defined如何解决
问题原因分析
- 全局变量未提前初始化:你仅在
on_message回调中声明了global test,但没有在模块顶层预先定义该变量。如果showdata被调用时还从未触发过MQTT消息回调,test变量就不存在,直接抛出未定义错误。 - MQTT客户端未实际运行:你写的
run()启动逻辑在if __name__ == '__main__'判断下,启动Django服务时(通常用python manage.py runserver)不会执行这段逻辑,MQTT客户端根本没启动,on_message永远不会被触发,test永远不会被赋值。而且client.loop_forever()是阻塞方法,直接在主进程运行会卡住Django的HTTP请求处理逻辑。 on_message回调参数错误:paho-mqtt的on_message回调的入参是固定的client、userdata、msg三个参数,你自行添加的request参数会导致回调触发时参数不匹配报错,无法完成test变量的赋值。
解决方案
- 顶层初始化全局变量
在文件导入语句下方预先定义test的初始值,避免未定义错误:
test = "暂未收到MQTT数据"
- 修复
on_message的参数错误
删掉多余的request参数:
def on_message(client, userdata, msg): global test test = msg.topic print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
- 单独启动MQTT线程避免阻塞Django
把MQTT客户端逻辑放到守护线程中,在Django启动时自动运行。修改后完整代码如下:
from django.shortcuts import render from paho.mqtt import client as mqtt_client import random import threading broker = 'localhost' port = 1883 topic = "Wind" client_id = f'python-mqtt-{random.randint(0, 100)}' # 初始化全局变量 test = "暂未收到MQTT数据" def connect_mqtt() -> mqtt_client: def on_connect(client, userdata, flags, rc): if rc == 0: print("Connected to MQTT Broker!") else: print("Failed to connect, return code %d\n", rc) client = mqtt_client.Client(client_id) client.on_connect = on_connect client.connect(broker, port) return client def subscribe(client: mqtt_client): def on_message(client, userdata, msg): global test test = msg.topic print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic") client.subscribe(topic) client.on_message = on_message def run_mqtt(): client = connect_mqtt() subscribe(client) client.loop_forever() # 启动MQTT守护线程,不阻塞Django主进程 mqtt_thread = threading.Thread(target=run_mqtt, daemon=True) mqtt_thread.start() def showdata(request): context = test return render(request, 'index.html', {'data': context})
内容的提问来源于stack exchange,提问作者terry555
相关产品推荐
相关产品推荐

