Django执行原生sql时, 解决防注入占位符的%与LIKE模糊查询的%歧义导致sql解析失败问题

在Django中,当内置查询功能不足时,可能需要使用原生SQL。为了防止SQL注入,官方推荐使用params参数列表传递值,而非直接拼接。例如,在模糊匹配查询中,%应放在params列表中,用%%在SQL中转义。文章展示了正确处理LIKE条件和参数绑定的方式。

当Django ORM的内置函数满足不了查询需求时, 有时需要执行原生sql, 官方文档推荐通过params参数列表传参, 而不是直接将参数拼接到sql语句中, 以防止sql注入

from django.db import connection

query_name = "test_name"
query_class = "test_class"
# 第1种, 直接将参数直接拼接到sql语句中
sql = f"SELECT * FROM tmp_table WHERE name='{test_name}' AND class='{query_class}'"
with connection.cursor() as cursor:
	cursor.execute(sql)

# 第2种(官方推荐), 在sql语句中用%s占位, 通过params参数列表传参(占位符周围不应包含引号)
sql = "SELECT * FROM tmp_table WHERE name=%s AND class=%s"
params = [query_name, query_class]
with connection.cursor() as cursor:
	cursor.execute(sql, params)

当涉及到字符串的模糊匹配查询时, 构造的原生sql中也会出现%, 此时LIKE条件语句中的%应该跟随参数一起放到params参数列表中, 直接放到原生sql语句中会导致解析失败

from django.db import connection

keyword = "小红"
query_class = "test_class"
# 第1种, 直接将参数直接拼接到sql语句中
sql = f"SELECT * FROM tmp_table WHERE name LIKE '%{keyword}%' AND class='{query_class}'"
with connection.cursor() as cursor:
	cursor.execute(sql)

# 第2种, 在sql语句中用%s占位, 通过params参数列表传参(占位符周围不应包含引号, sql中出现%时应当用%%来转义)
# 将LIKE的模糊匹配查询%放在sql语句中, 会导致sql解析失败
sql = "SELECT * FROM tmp_table WHERE name LIKE %%%s%% AND class=%s"
sql = "SELECT * FROM tmp_table WHERE name LIKE '%%%s%%' AND class=%s"
# 上述两种写法都会导致sql解析失败
sql = "SELECT * FROM tmp_table WHERE name LIKE %s AND class=%s"
keyword = f"%%{keyword}%%"
# 将%跟随参数一起拼接后放到params参数列表中, 问题完美解决
params = [keyword, query_class]
with connection.cursor() as cursor:
	cursor.execute(sql, params)

参考: https://www.cnblogs.com/zhujincheng/p/10323427.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值