rawa08
rawa08

Reputation: 135

Django search vector - no match on exact keyword

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

Answers (1)

ha-neul
ha-neul

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

Related Questions