Python Django:SQL注入-在原始查询中使用子查询
尝试将未执行的查询字符串传递到原始查询时出错,使用params参数作为子查询使用:Python Django:SQL注入-在原始查询中使用子查询,python,django,Python,Django,尝试将未执行的查询字符串传递到原始查询时出错,使用params参数作为子查询使用: from apps.bikeshare.models import Station qs = Station.objects.filter(...) subquery_string = qs.values('id').order_by().query raw = Station.objects.raw('SELECT * FROM bikeshare_station WHERE id IN (%s)', [su
from apps.bikeshare.models import Station
qs = Station.objects.filter(...)
subquery_string = qs.values('id').order_by().query
raw = Station.objects.raw('SELECT * FROM bikeshare_station WHERE id IN (%s)', [subquery_string])
查询将打印正确的SQL(WHERE
子句省略):
我知道这是危险的,因为这是SQL注入。但是,我想支持这一点,创建一个QuerySet方法(恰好需要原始查询),该方法可以在QuerySet链的末端使用,在该末端,过滤后的QuerySet作为子查询传递到原始查询中
params参数是否会降低任何风险,即使错误没有发生?或者我应该允许这种风险并使用基本的python字符串格式吗 我刚刚发布的方法无论如何都不能正常工作,因为
query
方法不能返回有效的SQL,即
qs = Station.objects.filter(name='Albert Gate, Hyde Park').values('id').order_by()
print(qs.query)
[out] SELECT "bikeshare_station"."id" FROM "bikeshare_station" WHERE "bikeshare_station"."name" = Albert Gate, Hyde Park
因为名称字符串没有被引用而爆炸
正如他在评论中指出的那样,似乎唯一的方法是执行查询并传入一个可以实现的ID列表:
qs = Station.objects.filter(name='Albert Gate, Hyde Park')
ids = list(qs.values_list('id', flat=True))
然后,您可以将id列表传递给原始查询,而不是字符串。您不能使用
query\u set.filter(id\u in=your\u list\u of id)的任何原因。
某处?@JonClements谢谢,刚刚意识到我也有另一个问题,请查看我的答案。出于好奇,我仍然不确定您在这里想做什么?查询ID子集中的名称,或者获取与名称匹配的ID列表,然后从中获取原始ORM生成的SQL,或者?只是想知道.raw
的东西是从哪里来的这一切…@JonClements请看我的另一个问题。我试图终止以原始查询结尾的queryset链。我想在原始查询中将查询“原样”作为子查询传递,以提供最大的灵活性。然而,由于query
返回的SQL无效,我无论如何也不能依赖它。
qs = Station.objects.filter(name='Albert Gate, Hyde Park').values('id').order_by()
print(qs.query)
[out] SELECT "bikeshare_station"."id" FROM "bikeshare_station" WHERE "bikeshare_station"."name" = Albert Gate, Hyde Park
qs = Station.objects.filter(name='Albert Gate, Hyde Park')
ids = list(qs.values_list('id', flat=True))