Python2将exec从不合格转换为合格

时间:2018-07-25 12:27:21

标签: python django orm exec eval

我必须在我的python代码中使用exec运行查询:

strfin = ''
a = []
a = qsearch.split(',')
for li in range(0, len(a)):
    b = a[li].split(':')
    if b[0].upper() == 'ID':
        strfin = strfin + ',id__contains=' + "'"+b[1]+"'"
    elif b[0].upper() == 'TEST NAME':
        strfin = strfin + ',id_test__test_main__descr__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'TEST TYPE':
        strfin = strfin + ',thread_ttype__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'TEST GROUP':
        strfin = strfin + ',thread_tgroup__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'SCHEDULE':
        strfin = strfin + ',thread_stype__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'THREAD NAME':
        strfin = strfin + ',thread_main__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'START':
        strfin = strfin + ',thread_startd__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'STOP':
        strfin = strfin + ',thread_stopd__contains=' + "'" + b[1].strip() + "'"
    elif b[0].upper() == 'USER':
        strfin = strfin + ',id_test__user_id__contains=' + "'" + b[1].strip() + "'"

afilexec = "%s%s%s" % ("activeThreads = t_threads.objects.filter(~Q(thread_status='DEAD'),", strfin[1:], ").select_related().distinct('thread_stag')")

如果我在代码末尾写:

exec(afilexec)

系统返回错误:

  

SyntaxError:函数'tabrefresh'中不允许使用不合格的exec,因为它包含带有自由变量的嵌套函数

我尝试将这个exec从不合格转换为合格:

exec afilexec in {}

编译时没有错误,但是当我运行函数时,我得到了:

  {p}中的

exec afilexec     文件“”,第1行,位于   NameError:名称“ t_threads”未定义

如何在代码中执行此查询?

非常感谢

1 个答案:

答案 0 :(得分:2)

您不应该这样做。 eval和exec几乎总是要避免的。在这种情况下,我们可以建立一个关键字参数字典,然后使用参数扩展将其传递给查询。

kwargs = {}
params = qsearch.split(',')
for item in params:
    b = item.split(':')
    kw = b[0].upper()
    val = b[1].strip()
    if kw == 'ID':
        kwargs['id__contains'] = val
    elif kw == 'TEST NAME':
        kwargs['id_test__test_main__descr__contains'] = val
    elif kw == 'TEST TYPE':
        kwargs['thread_ttype__contains'] = val
    elif kw == 'TEST GROUP':
        kwargs['thread_tgroup__contains'] = val
    ...
activeThreads = t_threads.objects.filter(~Q(thread_status='DEAD'),**kwargs).select_related().distinct('thread_stag')

(请注意,代码中我还做了其他一些更改:使用描述性变量名称,只执行一次strip / upper,并且永远不会遍历range(len(something))而是遍历整个事物本身。)