Reputation: 1045
I'm trying to perform a case-insensitive query. I would generally use __icontains, but since it doesn't support the .split() method, I'm stuck to using __in instead:
def search(request):
query = request.GET.get('q', '')
query = query.lower()
product_results = []
category_results = []
if query:
product_results = Product.objects.filter(Q(title__in=query.split())|
Q(brand__in=query.split())|
Q(description__in=query).split())
category_results = Category.objects.filter(title__in=query.split())
My problem is that the object fields usually have a the first letter capitalized, so an all lowercase query always returns negative.
Anyway around this?
Upvotes: 0
Views: 346
Reputation: 1045
thanks for sharing, i wrote up this quick hack, not elegant at all....
def search(request):
query = request.GET.get('q', '')
query = query.split()
product_results = []
category_results = []
if query:
for x in query:
product_results.extend(Product.objects.filter(Q(title__icontains=x)|
Q(brand__icontains=x)|
Q(description__icontains=x)))
category_results.extend(Category.objects.filter(title__icontains=x))
query = request.GET.get('q', '')
product_results = list(set(product_results))
category_results = list(set(category_results))
return render_to_response('search_results.html', {'query': query,
'product_results': product_results,
'category_results': category_results})
Upvotes: 1
Reputation: 2406
I have solved this problem by using exec to generate code from a string using icontains instead of in. I admit, it's sloppy and not elegant, and should be audited for security but it worked.
see the untested/pseudocode:
query = "product_results = Product.objects.filter("
for word in words:
query += "Q(title__icontains(word))|"
query += "Q(brand__icontains(word))|"
query += "Q(description__icontains(word))|"
query = query[:-1] # remove the trailing |
query += ")"
exec("product_results = "+query)
Again, this is probably not advisable, and I'm sure there's a better way to do this, but this fixed me up in a pinch once so I thought I would share. Also note, I don't use this code anymore as I've switched over to sqlalchemy which makes these kinds of dynamic queries a bit easier since it's "or" object accepts a list.
Upvotes: 1