首页 > 解决方案 > Django 搜索向量 - 完全关键字不匹配

问题描述

我有一个应用程序,客户可以按名称、品牌等搜索产品。问题是如果你写了确切的名称或确切的品牌名称将导致不匹配,如果你写了一半的名称或 id 将返回匹配

看法

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})

模型:

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>

标签: djangosearch

解决方案


您使用 searchvector 的方式是错误的。根据关于searchvector的文档

代替:

active_product = Product.objects\
.annotate(search=SearchVector('name', 'id', 'sex','brand_name'),)\
.filter(search__icontains=searchProduct)

active_product = Product.objects\
.annotate(search=SearchVector('name', 'id', 'sex','brand_name'))\     # no need to have another ","
.filter(search=searchProduct)   # remove icontains

推荐阅读