Reputation: 5507
I have the following get and get_queryset methods in my CustomersListView class:
def get(self, request, *args, **kwargs):
"""
:param request:
:param args:
:param kwargs:
:return:
"""
self.id = request.GET.get('id')
self.f_name = request.GET.get('f_name')
self.m_name = request.GET.get('m_name')
self.l_name = request.GET.get('l_name')
self.r_name = request.GET.get('r_name')
self.p_no = request.GET.get('p_no')
self.gender = request.GET.get('gender')
return super(CustomersListView, self).get(request, *args, **kwargs)
def get_queryset(self):
"""
:return:
"""
query_list = [Q(id=self.id), Q(first_name__contains=self.f_name), Q(middle_name__contains=self.m_name),
Q(last_name__contains=self.l_name), Q(relative_name__contains=self.r_name),
Q(phone_no_1__contains=self.p_no), Q(phone_no_2__contains=self.p_no), Q(gender=self.gender),
]
return Customer.objects.filter(reduce(operator.and_, query_list))
User can submit data in following ways:
1: If user submits empty form then all the entries of the Customer model should be returned.
2: If user submits data in any one field then data should be filtered according to that field.
3: If user submits data in more then one field then query should filter data according to both field i mean(and).
Note: request.GET.get()
will return u''
for the empty form fields. And id
should be integer
for searching customer model by id
not by unicode string u''
.
For example :
>>> Customer.objects.filter(Q(id=None) and Q(first_name__contains='Secon') and Q (last_name__contains=''))
[<Customer: vaibhav kumar jain >, <Customer: second customer second customer second customer >]
But i want results corresponding to only Q(first_name__contains='Secon')
lookup which is
<Customer: second customer second customer second customer >
not
[<Customer: vaibhav kumar jain >, <Customer: second customer second customer second customer >]
Upvotes: 0
Views: 76
Reputation: 2136
You can do this with keyword arguments and some filtering:
def get_queryset(self):
# filters_map keys must match your queries
filters_map = {
'id': self.request.GET.get('id'),
'first_name__icontains': self.request.GET.get('f_name'),
'middle_name__icontains': self.request.GET.get('m_name'),
'last_name__icontains': self.request.GET.get('l_name'),
'relative_name__icontains': self.request.GET.get('r_name'),
'phone_no_1__contains': self.request.GET.get('p_no'),
'phone_no_2__contains': self.request.GET.get('p_no'),
'gender': self.request.GET.get('gender')
}
# leave out empty strings
query = dict((key, value) for key, value in filters_map.iteritems() if value)
return Customer.objects.filter(**query)
A bit more about keyword arguments.
PS: I think it makes more sense to filter the queryset in the get_queryset
method.
Upvotes: 1