Reputation: 977
I have create model with this fields:
field_1 , field_2, field_3, ... , field_n
And I want to filter
all objects that these k fields:
field_1 , field_2, .... , field_k
of those objects is n't Null
.
My wrong answer:
I did think that I must create this list of fields that I want to set in my query:
my_list = [`field_1` , `field_2`, .... , `field_k`]
and create my query like this:
my_objects = Class.objects.filter([ (eval(field_name +"__isnull = False") ) for field_name in my_list ])
But it was wrong. How can I do that?
Upvotes: 2
Views: 563
Reputation: 476624
You make things too complicated, you can not construct a list with strings and pass it to filter(..)
in the hope that it will work. Furthermore eval(..)
does not work that way, and even if it did, it would result in severe security risks. eval(..)
and exec(..)
should be avoided as much as possible, since from the moment someone manages to "inject" a string into it, they can run arbitrary code on your server, and thus try to "dump the database", etc. See this answer for a more in-depth analysis on why "Eval is bad practice".
You can construct a list of fields names (so strings):
my_list = ['field_1', 'field_2', 'field_k']
Then we can construct a dictionary and perform dictionary unpacking, like:
Class.objects.filter(**{'{}__isnull'.format(f): False for f in my_list})
The two asterisks (**
), will thus make a function call, such that f(**{'a': 4, 'b': 2})
, is the same as f(a=4, b=2)
, and thus here it will make a call like .filter(field_1__isnull=False, field_2__isnull=False, field_k__isnull=False)
.
Or since python-3.6, we can make use of f-strings:
Class.objects.filter(**{f'{f}__isnull': False for f in my_list})
Upvotes: 2