Django视图中如何比对用户输入与数据库存储值去除重复条目?
报错原因
你遇到的报错是因为cursor.fetchall()返回的是由元组组成的列表,每一行查询结果对应一个元组,哪怕你只查了一个字段,返回的每个元素也是类似('TenGigabitEthernet1/0/1',)的结构,直接遍历righttable的元素当作列表索引使用,就会触发「列表索引必须是整数或切片,不能是元组」的报错。
实现方案
我们可以先把数据库查询到的接口名转为集合,利用集合O(1)的查询效率快速做去重比对,最后用参数化查询插入新数据避免SQL注入风险,修改后代码如下:
# 查询数据库已有接口,提取为纯字符串集合 cursor.execute(f"SELECT interface FROM {tablename} WHERE id >=2") db_interface_set = set(item[0] for item in cursor.fetchall()) # 过滤出数据库中不存在的待新增接口 to_add_interfaces = [iface for iface in interfacelist if iface not in db_interface_set] # 参数化查询批量插入新接口,若使用的是SQLite占位符改为?即可 for iface in to_add_interfaces: cursor.execute(f"INSERT INTO {tablename}(interface) VALUES(%s)", (iface,)) cursor.close()
补充说明
- 用集合做匹配的效率远高于遍历列表逐个比对,数据量越大优势越明显
- 禁止直接用f字符串拼接SQL值,参数化查询会自动处理特殊字符转义,避免SQL注入漏洞
- 如果表名
tablename是用户可控的,需要提前做白名单校验,避免SQL注入风险
内容的提问来源于stack exchange,提问作者L.Calvin
相关产品推荐
相关产品推荐

