Possible Duplicate:
filter using Q object with dynamic from user?
I am working on a filter feature in my app. I send a comma separated string via jquery to Django (within jquery I replace the space with a +, so that it can be sent over the wire).
/?ajax&sales_item=t2,+t1
Now in the view when I retrieve the GET parameters, I can see Django has already replaced the + with a space, which is great. Then I split the keywords by comma and strip the whitespace.
sales_item_raw = request.GET['sales_item']
sales_item_keywords = sales_item_raw.split(',')
I need first to check if the given names even exist as sales item. I have to use a icontains, hence sales_items can be more than one item.
for item in sales_item_keywords:
sales_items = profile.company.salesitem_set.filter(item_description__icontains=item.strip())
Last but not least the queryset is used to filter deals for the given sales_items:
deals_queryset = deals_queryset.filter(sales_item__in=sales_items)
If the user filters for only one keyword that would work fine, however if there are two keywords the sales_items will be obviously overwritten in each loop iteration.
What is the most performant way to solve this? Shall I just append the content of sales_itemsin each iteration to a list outside the loop? And eventually send the new list to the final deals_queryset.filter?
I am not sure if this is a good way to solve this…
Use Django’s Q object to create “or” logic in your filter.
This is ugly code, as I’m not sure how to handle the initial Q elegantly, as I’m not sure what is an “empty” Q to which you can chain all other Qs, including the first one. (I’m guessing you could use
Q(pk=pk)but that’s ugly in a different way.)EDIT: Ignacio’s link above shows the way, i.e.