Reputation: 950
I want to do a basic query search. I want to use the fields city
and area
to perform datatbase lookup.
I want a case whereby if the user input the city and area in the search field, it should return the results. Also if the user input either city or area it should return the result.
The below code didn't return any result when I input city and area in the search field, and I have objects related to the query saved in the database. Instead it returns 'no result'.
def my_search(request):
try:
q= request.GET['q']
hots= Place.objects.filter(Q(city__icontains=q)&Q(area__icontains=q))
c_hos=hots.count()
return render(request, 'search/own_search.html',{'hots':hots, 'q':q, 'c_hos':c_hos})
except KeyError:
return render(request, 'search/own_search.html')
I even tried using the |
and it won't return any result when I input the city and area together in the field.
What am I missing?
Upvotes: 0
Views: 386
Reputation: 846
In general all the kwargs in filter() are AND'ed together you can know more about complex look ups using Q in the Django Documentation
# For performing OR operation
hots= Place.objects.filter(Q(city__icontains=q) | Q(area__icontains=q))
# For performing AND operation
hots= Place.objects.filter(Q(city__icontains=q), Q(area__icontains=q))
should also be working without any problem.
EDIT:
If the variable "q" from the request contains both city and area in a single variable, this wont return anything since the logic you are using is not appropriate.
Assume a table
State City
California San Francisco
Then if in your q="California San Francisco", then whole query doesn't match anything.
__icontains works with something like this
q = "San" # Or q = "Franscisco"
result = Place.objects.filter(Q(state__icontains=q) | Q(city_icontains=q))
Then result would be having the object with state=California and city=San Franscisco.
It would be easy for you to use the same logic but try to enter either city or place in order to work with it. It would be much simpler.
Re-Edit:
If you want to filter every word in a string you can try using this:
list = str(q).split()
result = Place.objects.filter(reduce(operator.and_, (Q(place__contains=x) | Q(city__contains=x) for x in list)))
# Adding .distinct() to the filter might clean the QuerySet and remove duplication in this scenario.
Upvotes: 1
Reputation: 11
You should go with the or operator "|" if you want to accept a query of city only or area only. I suggest you to print variable q after being taken from request to see what in it and do your database query again. Another thought is maybe you should split the value of q into city and area.
Upvotes: 1