How would I go about using the django.db.models Q module to query multiple lines of input from a list of data using a <textarea>
html input field? I can query single objects just fine using a normal html <input>
field. I've tried using the same code as my input field, except when requesting the input data, I attempt to split the lines like so:
def search_list(request):
template = 'search_result.html'
query = request.GET.get('q').split('\n')
for each in query:
if each:
results = Product.objects.filter(Q(name__icontains=each))
This did not work of course. My code to query one line of data (that works) is like this:
def search(request):
template = 'search_result.html'
query = request.GET.get('q')
if query:
results = Product.objects.filter(Q(name__icontains=query))
I basically just want to search my database for a list of data users input into a list, and return all of those results with one query. Your help would be much appreciated. Thanks.
Based on your comments, you want to implement OR-logic for the given q
string.
We can create such Q
object by reduce
-ing a list of Q
objects that each specify a Q(name__icontains=...)
constraint. We reduce this with a "logical or" (a pipe in Python |
), like:
from django.db.models import Q
from functools import reduce
from operator import or_
def search_list(request):
template = 'search_result.html'
results = Product.objects.all()
error = None
query = request.GET.get('q')
if query:
query = query.split('\n')
else:
error = 'No query specified'
if query:
results = results.filter(
reduce(or_, (Q(name__icontains=itm.strip()) for itm in query))
)
elif not error:
error = 'Empty query'
some_context = {
'results' : results,
'error': error
}
return render(request, 'app/some_template.html', some_context)
Here we thus first check if q
exists and is not the empty string. If that is the case, the error is 'No query specified'
. In case there is a query, we split that query, next we check if there is at least one element in the query. If not, our error is 'Empty query'
(note that this can not happen with an ordinary .split('\n')
, but perhaps you postprocess the list, and for example remove the empty elements).
In case there are elements in query
, we perform the reduce(..)
function, and thus filter the Product
s.
Finally here we return a render(..)
ed response with some_template.html
, and a context that here contains the error
, and the result
.