Reputation: 571
I am trying to build Q objects dynamically. This is my code:
class StudentiRicerche(ListAPIView):
serializer_class = StudentiLista
def get_queryset(self):
query_params = self.request.query_params
q_objects = Q()
for k, v in query_params.items():
param = '{0}__icontains={1}'.format(k, v) # k and v are dynamic values
q_objects &= Q(param)
queryset = Studenti.objects.filter(q_objects) # Here i get an error
return queryset
With this code I am getting a ValueError on the line where I use filter
I have also tried to use a list of Q objects insted of Q objects directly in this way:
class StudentiRicerche(ListAPIView):
serializer_class = StudentiLista
def get_queryset(self):
query_params = self.request.query_params
q_list = []
for k, v in query_params.items():
param = '{0}__icontains={1}'.format(k, v)
q_list.append(Q(param)) # Q with 'and' condition
queryset = Studenti.objects.filter(*q_list) # here I get an error also
return queryset
But here I am getting again the same error! Any idea??
Upvotes: 0
Views: 608
Reputation: 383
Simplify. You don't need use Q:
class StudentiRicerche(ListAPIView):
serializer_class = StudentiLista
def get_queryset(self):
query_params = self.request.query_params
queryset = Studenti.objects.filter(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
return queryset
Explain:
.filter
and Q()
is dictionary, not list.filter
and Q()
use named-arguments, such as: .filter(name__icontains='Ivan', email__icontains='mail.com')
.filter(**{'name__icontains':'Ivan', 'email__icontains': 'mail.com')
.filter(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
Q()
dynamically you must use dictionary: Q(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
and in addition
.filter(is_active__isnull=False, **{'{}__icontains'.format(k):v for k,v in query_params.items() })
Upvotes: 2