Reputation: 135
I have an application where customer can search for products by name, brand etc. the problem is if you write the exact name or the exact brand name will result in no match, if you write the half of the name or the id will return a match
view
def home(request):
active_product = Product.objects.all().filter(show=True).order_by('-score', '-brand_name')
#Paginator
paginator = Paginator(active_product, 20)
page = request.GET.get("page")
active_product = paginator.get_page(page)
#Filterd by search
searchProduct = request.GET.get("do_search")
if searchProduct:
active_product = Product.objects.annotate(search=SearchVector('name', 'id', 'sex','brand_name'),).filter(search__icontains=searchProduct)
return render(request, 'index.html', {'productObject': active_product})
Model:
class Brand(models.Model):
name = models.CharField(unique=True, max_length=30, blank=False,null=True)
def __str__(self):
return self.name
class Product(models.Model):
genderChoice = (('W','Female'),('M','Male'),('U','Unisex'))
id = models.BigIntegerField(primary_key=True, null=False)
brand_name = models.ForeignKey(Brand, to_field='name', on_delete=models.CASCADE, related_name='brand_name', default='Brand Name')
name = models.CharField(max_length=300, blank=False,null=False)
sex = models.CharField(max_length=7,choices=genderChoice, default='U')
p_type = models.CharField(max_length=50, blank=True,null=True)
image_link = models.CharField(max_length=500, blank=True,null=True)
stock_price = models.DecimalField(max_digits=10,decimal_places=2, default=999.00)
show = models.BooleanField(default=False)
in_stock = models.BooleanField(default=False)
created = models.DateField(auto_now_add=True)
volume= models.CharField(max_length=50, blank=True,null=True)
score = models.IntegerField(default=1)
price = models.DecimalField(max_digits=100, default=999.00, decimal_places=2)
def __str__(self):
template = '{0.name} {0.brand_name} {0.volume} {0.price}'
return template.format(self)
html:
<form class="my-2 my-lg-0" action="{% url 'home'%}" method="GET">
<div class="input-group mb-3">
<input type="search" class="form-control border-dark" placeholder="search" aria-label="Search" aria-describedby="button-addon2" name="do_search">
<button class="ml-1 btn btn-outline-dark" type="submit" id="button-addon2">Search</button>
Upvotes: 0
Views: 262
Reputation: 3258
The way you use searchvector is wrong. According to the doc about searchvector
replace:
active_product = Product.objects\
.annotate(search=SearchVector('name', 'id', 'sex','brand_name'),)\
.filter(search__icontains=searchProduct)
with
active_product = Product.objects\
.annotate(search=SearchVector('name', 'id', 'sex','brand_name'))\ # no need to have another ","
.filter(search=searchProduct) # remove icontains
Upvotes: 1