You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中从URL生成二维码?设备添加失败问题排查

问题排查与修复方案

以下是你的代码中导致设备添加失败的关键问题,以及对应的修复方法:

1. 内存设备实例未同步数据库更新的URL

在create_url中你用filter.update()更新了数据库里的screen_url,但内存中的device实例并未同步最新值。调用create_qr时,device.screen_url还是初始空值,会导致二维码生成失败,中断整个流程。

修复方法:
直接给内存中的device对象赋值后保存,或更新数据库后重新获取实例:

def create_url(self, layout, device):
    screen_url = base_screen_url + device.device_id + ".html"
    # 直接更新内存实例并保存,替代filter.update
    device.screen_url = screen_url
    device.save()
    
    html = self.edit_device_url_html(layout, device)
    s3.put_object(Bucket=device_url_bucket, Key=str(device.device_id) + ".html", Body=html, ACL='public-read',
                  ContentType='text/html', CacheControl='no-cache, no-store, must-revalidate')
    return device  # 返回更新后的实例

调用时接收更新后的device:

device = self.create_url(empty_layout, device)
self.create_qr(device)

2. 设备ID生成存在并发冲突风险

用len(Device.objects.all())计算序号,多用户同时添加设备时会生成重复的device_id,触发数据库唯一约束报错,导致添加失败。

修复方法:
改用UUID生成唯一ID,避免并发冲突:

import uuid
# 替换原device_id生成逻辑
device.device_id = f"{self.random_string_generator()}-{uuid.uuid4().hex[:8]}"

3. 二维码保存路径可靠性不足

硬编码'media/' + qr_name,若media目录不存在会抛出IO错误,中断流程。应利用Django的MEDIA_ROOT配置:

from django.conf import settings
import os

def create_qr(self, device):
    if not device.screen_url:
        raise ValueError("设备未生成screen_url,无法生成二维码")
    
    qr_name = f'qr_{device.device_id}.png'
    # 确保media目录存在
    media_path = settings.MEDIA_ROOT
    os.makedirs(media_path, exist_ok=True)
    qr_path = os.path.join(media_path, qr_name)
    
    qr = make(device.screen_url)
    qr.save(qr_path)

4. VMIscreen为true的分支未处理URL和二维码生成

当前仅在VMIscreen为false时生成URL和二维码,不符合“每个设备都需生成二维码”的需求。需补充该分支的逻辑:

if device.VMIscreen == "true":
    # 假设auto_create_new_layout会返回生成的layout对象
    layout = self.auto_create_new_layout(request, device)
    device = self.create_url(layout, device)
    self.create_qr(device)
else:
    empty_layout = Layout()
    device = self.create_url(empty_layout, device)
    self.create_qr(device)

5. 缺少异常捕获与错误反馈

流程中无异常捕获,任何一步出错(如用户不存在、数据库保存失败、S3上传失败)都会直接抛出异常,导致添加失败且无反馈:

def add_new_device(self, request):
    try:
        user = User.objects.get(username=request.data["username"])
        device = Device()
        device = self.write_fields_to_object(device, request.data, user)
        # 用UUID生成唯一device_id
        import uuid
        device.device_id = f"{self.random_string_generator()}-{uuid.uuid4().hex[:8]}"
        device.save()

        self.set_station_data(request.data, device)

        if device.VMIscreen == "true":
            layout = self.auto_create_new_layout(request, device)
            device = self.create_url(layout, device)
            self.create_qr(device)
        else:
            empty_layout = Layout()
            device = self.create_url(empty_layout, device)
            self.create_qr(device)
        
        self.create_notification(user, device, "add", "device", "has added new Device")
        return "ok"
    except User.DoesNotExist:
        return "用户不存在"
    except Exception as e:
        # 记录错误日志
        import logging
        logging.error(f"添加设备失败: {str(e)}")
        return f"添加失败: {str(e)}"

内容的提问来源于stack exchange,提问作者idil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:32:47