Reputation: 3484
I am working on an HTML form to filter multiple model fields.
How to build the view so a single queryset is returned even with changing queries?
My form will pass the inputs as kwargs so request will be like this -
/search/?order_by=newest
/search/?q=<string>&order_by=newest
/search/?q=<string>&order_by=newest&country=US
These would filter upon:
string
in query (q=...)order_by
to order the querysetcountry
to filter the results by a location fieldI'm trying to have a single query in the view to remove complexity and keep the view as simple as possible. How can I take all of these potential variations and pass through a single get_queryset
method?
Here is what I have right now.
def get_queryset(self):
keywords = self.request.GET.get('q') or None
order_by = self.order_by_options.get(
self.request.GET.get('order_by')) or '-date_of_price'
if keywords:
query = SearchQuery(keywords)
vectors = SearchVector('name', weight='A')
qs = self.model.objects_for_search.annotate(search=vectors).filter(
search=query).order_by('sold', order_by, '-modified')
else:
qs = self.model.objects_for_search.order_by('sold', order_by, '-modified')
return qs[0:500]
The issue with the code above is that the more attributes I add, the more if statements
. This code has the if statement
for keywords, and that doesn't feel elegant/pythonic to me. Adding another if statement
for the country query would definitely be odd.
Upvotes: 1
Views: 1287
Reputation: 582
kwargs = {
'q': request.GET.get('q',''),
'order_by_field': request.GET.get('order_by','-date_of_price'),
'country': request.GET.get('country','-date_of_price')
}
Get all query parameter and make a kwargs with these. we don't have options other than if else. For eg -
filter_kwargs = {}
if 'q' in kwargs and kwargs['q']:
filter_kwargs['keyword'] = kwargs['q']
if 'country' in kwargs and kwargs['country']:
filter_kwargs['country'] = kwargs['country']
result = self.query.objects.filter(**filter_kwargs) \
.order_by(kwargs['order_by_field'])
Upvotes: 1