I'm learning django and I'm trying to make a online shop for learning. Currently I have a problem in how to make a search bar in django. I have model called "Car" in my models.py and it contains fields like name, price of the car and also it has a field called "tag" and I want to make a search bar using this field. I want that when user types a tag in the webpage of site, django searches and shows the items that have the same tag.
I tried to solve my problem by reading the documents but it didn't help.
Here is an example of a view and some template code that would handle the search you want to execute (adapted from Bidhan Majhi's answer to this StackOverflow question):
class SearchView(ListView):
model = Car
template_name = 'search.html'
context_object_name = 'all_search_results'
def get_queryset(self):
result = super(SearchView, self).get_queryset()
query = self.request.GET.get('search')
if query:
postresult = Car.objects.filter(tag__contains=query)
result = postresult
else:
result = None
return result
<form method="GET" action="" >
<input type="search" name="search">
<button type="submit"> Search </button>
</form>
{% for car in all_search_results %}
<h2>{{ car.year }} {{ car.make }} {{ car.model }}</h2>
{% comment %} Add whatever else for each Car model returned{% endcomment %}
{% empty %}
<h2>add something to show no results</h2>
{% endfor %}
tags
field is a ManyToManyField)The above view would work as long as your tag
is just a CharField, but if your tags
field is a ManyToManyField, you would have to modify the postresult = Car.objects.filter(tag__contains=query)
line so that it would work through a related Tag model (postresult = Car.objects.filter(tags__text__contains=query)
).
This is how that would look:
from django.db import models
class Tag(models.Model):
text = models.CharField(max_length=20)
from django.db import models
from tag.models import Tag
import datetime
def year_range():
this_year = datetime.date.today().year
return [(r, r) for r in range(
1860, this_year+2
)
]
class Car(models.Model):
"""model for thoughts that come into my mind"""
year = models.PositiveSmallIntegerField(
choices=year_range
)
make = models.CharField(max_length=50)
model = models.CharField(max_length=50)
tags = models.ManyToManyField(
Tag, related_name="cars"
)
from django.views import generic
from .models import Car
# Create your views here.
class SearchView(generic.ListView):
model = Car
template_name = 'search.html'
context_object_name = 'all_search_results'
def get_queryset(self):
result = super(SearchView, self).get_queryset()
query = self.request.GET.get('search')
if query:
postresult = Car.objects.filter(tags__text__contains=query)
result = postresult
else:
result = None
return result
The template would be the same as above. I just tried it in a django sandbox project I have, and it worked great :)