Reputation: 1283
On my homepage I have a search bar and when you search something it redirects you to a page with the results(titles and document types). On the left side of the page I want to implement a filter by document type.
After the search my url looks like this: http://127.0.0.1:8000/search/?q=something
After applying the filter: http://127.0.0.1:8000/search/?document_type=Tehnical+report
I don't know how to implement the filters to search just in the objects list filtered by the query (q) on the search page. Also, I'm not sure if the url should look like this : http://127.0.0.1:8000/search/?q=something&document_type=Tehnical+report
or like this http://127.0.0.1:8000/search/?document_type=Tehnical+report
after applying the filter.
models.py
DOCUMENT_TYPES = [
('Tehnical report','Tehnical report'),
('Bachelor thesis','Bachelor thesis'),
...
]
class Form_Data(models.Model):
title = models.CharField(unique=True, max_length=100, blank=False)
author = models.CharField(max_length=100)
document_type = models.CharField(choices=DOCUMENT_TYPES, max_length=255, blank=False, default=None)
views.py
def search_list(request):
object_list = Form_Data.objects.none()
document_types = DOCUMENT_TYPES
query = request.GET.get('q')
query_list = re.split("\s|(?<!\d)[,.](?!\d)", query)
document_type_query = request.GET.get('document_type')
for item in query_list:
object_list |= Form_Data.objects.filter( Q(title__icontains=item) | Q(author__icontains=item))
return render(request, "Home_Page/search_results.html")
home_page.html
<div class="Search">
<form action="{% url 'home_page:search_results' %}" method="get">
<input id="Search_Bar" type="text" name="q">
<button id="Button_Search" type="submit"></button>
</form>
</div>
search_results.html
{% for form_data in object_list %}
<h5>{{ form_data.title }}</h5>
<h5>{{ form_data.document_type }}</h5>
{% endfor %}
<form method="GET" action=".">
<select class="form-control" name="document_type">
{% for tag, label in document_types %}
<option value="{{ tag }}">{{ tag }}</option>
{% endfor %}
</select>
</form>
Upvotes: 0
Views: 505
Reputation: 415
In my opinion you are doing it the wrong way... I mean I didn't understand why you are looping your query
for filtering. As far as I know it was looping every letters of your query.
I was doing it I would do it like this (using my own example):
<form action='{% url 'products:search' %}' method='get'>
<input type='text' name='q' id='search' value='' >
<select name='category' id='category'>
<option value='' selected ></option>
<option value='packet'>Packet</option>
<option value='food'>Food</option>
<option value='vegetable'>Vegetable</option>
</select>
<input type='button' value='submit' >
</form>
views.py:
def search(request):
products = None
query = request.GET.get('q')
category = request.GET.get('category')
if query:
products = Product.objects.filter(
Q(name__icontains=query)|
Q(brand__icontains=query)
)
if category:
# since it is a choice field in the model
products |= Products.objects.filter(category=category)
context = {
'products': products,
}
return render(request, 'products/search_products.html', context)
in this case if I press the submit button I would get a url like:
http://localhost:8000/products/search/?q=something&category=food
with this data I can filter products by name or any other fields I want.
I don't see any instance where someone would enter their query and search result will have all the products that has any of the letters entered in the input field.
Upvotes: 1
Reputation: 7424
This would be the model filtering:
query = request.GET.get('q')
document_type_query = request.GET.get('document_type')
object_list = FormData.objects.none()
for item in query.split():
item_qs = FormData.objects.filter(Q(title__icontains=item) | Q(author__icontains=item))
if document_type_query:
item_qs = item_qs.filter(document_type=document_type_query)
object_list |= item_qs
return render(request, "Home_Page/search_results.html", {"object_list": object_list})
And this is the URL:
http://127.0.0.1:8000/search/?q=something%20with%20spaces&document_type=Tehnical+report
Upvotes: 1