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

Django中raw原生查询ORDER BY列参数传递无效该如何解决

问题原因

你遇到的问题不是Django的raw()方法不支持传参,而是数据库参数化查询本身就不支持将标识符(列名、表名、关键字等)作为参数绑定。

参数化查询的设计目的是绑定查询值,绑定的时候数据库驱动会自动给传入的参数添加字符串引号、做转义处理,你原来的写法最终执行的SQL实际是SELECT * FROM data_table ORDER BY '你的列名字符串',相当于按固定字符串常量排序,自然不会生效。

解决方法
  • 方案1:白名单校验+字符串拼接(最常用,适合必须用原生SQL的场景)
    首先要对传入的排序字段做白名单校验,避免SQL注入风险,再通过Python字符串格式化拼入SQL语句,示例代码如下:
# 先定义允许排序的字段白名单,只能从列表里选,避免SQL注入
ALLOWED_ORDER_FIELDS = ['id', 'create_time', 'title', 'amount']
# 校验排序字段合法性,不合法就用默认排序字段
if order_col_name not in ALLOWED_ORDER_FIELDS:
    order_col_name = 'id'

# 直接把校验后的字段名拼入SQL
data_list = Data.objects.raw(
    f'SELECT * FROM data_table ORDER BY {order_col_name}'
)

如果需要支持倒序排序,可以再加参数判断,比如传order_type是asc/desc,同样加白名单校验后拼入即可。

  • 方案2:ORM原生排序(适合不需要复杂原生查询的场景)
    如果你的原生SQL只是简单查全表,完全可以直接用Django ORM的order_by方法,自动规避SQL注入问题:
data_list = Data.objects.all().order_by(order_col_name)
  • 方案3:Python内存排序(仅适合数据量极小的场景)
    如果数据量很小,也可以在拿到raw查询结果后用Python代码排序,不过数据量超过千条就不推荐,性能损耗很大:
data_list = sorted(Data.objects.raw('SELECT * FROM data_table'), key=lambda x: getattr(x, order_col_name))
安全提醒

绝对不要直接把未校验的用户输入内容直接拼入SQL语句,必须经过白名单校验,否则会存在严重的SQL注入漏洞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:54:06