Django判断Host存在后调用create_devices存储网络设备数据问题
问题1修复方案
原逻辑失效的原因
- 你把
Host记录判断和create_devices()调用写在了DetailView的类定义阶段,这段代码只会在Django项目启动加载模块时执行一次,后续用户发起请求不会重新触发判断 Host.objects.values()返回的是Django QuerySet对象,哪怕没有数据空QuerySet的布尔值也是True,所以你的判断条件永远成立,无法起到校验作用
正确实现方式
首先判断是否存在Host记录应该用Django内置的exists()方法,是查询数据库是否有记录的最高效方式。其次把逻辑放到视图的请求处理流程中,比如重写get_queryset方法:
class DeviceGetAll(DetailView): model = Device def get_queryset(self): # 每次请求时判断是否存在Host记录 if Host.objects.exists(): create_devices() return super().get_queryset()
另外你create_devices里的重复设备判断逻辑有问题,原判断是拿MAC字符串和Device对象QuerySet做包含判断,永远返回False,修正如下:
def create_devices(): """ 若设备不存在则在数据库中创建设备条目 :return: 存储在数据库中的设备对象列表 :rtype: list ["Device", "Device", ...] """ available_devices = get_available_devices_in_list() arp_table_of_all_hosts = get_arp_table_linux() dev_list = [] for deviceip in available_devices: devmac = arp_table_of_all_hosts.get(deviceip) if not devmac: continue # 修正重复判断逻辑 if Device.objects.filter(mac_address=devmac).exists(): continue devname = "unknown" dev = Device(hostname=devname, mac_address=devmac, ipv4_address=deviceip) dev.save() dev_list.append(dev) return dev_list
问题2合理性说明
直接在视图请求流程中无交互存储数据的合理性分场景判断:
- 不推荐的场景:如果扫描网络操作耗时较长、接口请求量高,这种做法会导致用户请求阻塞、响应超时,同时高并发下会出现重复扫描、重复写入的问题,生产环境建议把扫描逻辑改成异步任务,在Host记录新增/更新时触发一次,或者配置定时任务定期扫描,不要耦合在请求生命周期里
- 可接受的场景:如果是内部低频率使用的小工具、扫描耗时在毫秒级、并发量极低,这种实现没有问题,足够简单轻量化
内容的提问来源于stack exchange,提问作者kadopsdong
相关产品推荐
相关产品推荐

