首页 > 解决方案 > 优化中的 Django 原始 SQL?

问题描述

我觉得我的代码不是很pythonic,如何优化?</p>

代码

lamp_keys=["ids"]
if len(lamp_keys) == 1:
    rsql = f"""
                SELECT * from brelation
                where source_key = '{lamp_keys[0]}' and target_concept='aaa'
            """
else:
    rsql = f"""
                SELECT * from brelation
                where source_key in {tuple(lamp_keys)} and target_concept='aa'
            """
robjs = RelationModel.objects.raw(rsql)

如果lame_keys长度为1,如果使用in一定是错误的,例如:

SELECT * from `brelation` WHERE source_key in ('xx',) and target_concept='aa'

标签: pythondjango

解决方案


您犯了自己格式化原始 SQL 的非常危险的错误。假设在部分:

where source_key = '{lamp_keys[0]}'

一些用户决定他们想要恶意并给出一些价值,比如'; DROP TABLE brelation; --lamp_keys[0]可以想象会发生什么是吗?你的桌子会掉下来!这称为SQL 注入

当您想在原始查询中使用某些用户定义的值时,请始终使用参数化查询。参考:将参数传递给 raw() [Django docs]

rsql = f"SELECT * from brelation where source_key in %s and target_concept='aaa'"
robjs = RelationModel.objects.raw(rsql, [lamp_keys])

进一步看,您甚至不需要使用原始查询,如下所示的内容等同于您的原始查询:

robjs = RelationModel.objects.filter(source_key__in=lamp_keys, target_concept='aaa')

推荐阅读