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

被折叠的 条评论
为什么被折叠?



