0

I have to run a query with exec in my python code:

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')")

if i at the end of code write:

exec(afilexec)

System return error:

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

i try to trasform this exec from unqualified to qualified like this:

exec afilexec in {}

no error in comiling but when i run my function i got:

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

How can i exec this query in my code?

Thanks in adcance

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Manuel Santi
  • 1,106
  • 17
  • 46
  • 2
    Aaargghh... Don't use `exec`, or `eval` (better known as *pure* `evil`)... Unless you really need to, it is horribly unsafe. Use `**kwargs`... – Willem Van Onsem Jul 25 '18 at 12:29
  • Sorry how can i run my str (afilexec) using **kwargs? Thanks – Manuel Santi Jul 25 '18 at 12:32
  • 1
    You should not construct such `afilexec` anyway, but a dictionary that contains the parameters you want to pass to the function: see here https://stackoverflow.com/questions/1769403/understanding-kwargs-in-python – Willem Van Onsem Jul 25 '18 at 12:33

1 Answers1

2

You shouldn't do this. eval and exec are almost always to be avoided. In this case, we can build up a dictionary of keyword arguments and then use parameter expansion to pass them to the query.

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')

(Note, there were a couple of other things in your code that I've changed: use descriptive variable names, only do the strip/upper once, and never iterate over range(len(something)) but over the thing itself.)

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895