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

Python2 transform exec from unqualified to qualified

我必须 运行 在我的 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)

系统return错误:

SyntaxError: unqualified exec is not allowed in function 'tabrefresh' because it contains a nested function with free variables

我尝试将此 exec 从不合格转换为合格,如下所示:

exec afilexec in {}

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

exec afilexec in {} File "", line 1, in NameError: name 't_threads' is not defined

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

提前致谢

你不应该这样做。 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 一次,并且永远不要遍历范围(len(某事))但在事情本身。)