You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django应用自动补全搜索栏优化:实现容错式产品检索

解决Django搜索栏拼写错误、拆分关键词匹配问题

问题分析

你当前的代码用name__icontains=address做匹配,只能找到完整包含查询字符串的产品。当用户输入拆分的关键词(比如"dispo 1")或拼写接近的内容时,因为查询字符串不是产品名的连续子串,所以匹配不到结果。

解决方案

下面提供三种递进的优化方案,从简单到复杂,覆盖你的需求:

方案1:拆分关键词,多条件匹配

把用户输入的查询按空格拆分成多个关键词,要求每个关键词都出现在产品名中,这样"dispo 1"就能匹配同时包含"dispo"和"1"的产品。

修改后的视图代码:

from django.db.models import Q

def search_address(request):
    query = request.GET.get('query', '')
    payload = []
    if query:
        # 拆分关键词,过滤空字符串(避免用户输入多个空格)
        keywords = [kw.strip() for kw in query.split() if kw.strip()]
        if keywords:
            # 构建多条件Q对象,每个关键词都要icontains匹配
            q_objects = Q()
            for kw in keywords:
                q_objects &= Q(name__icontains=kw)
            
            # 获取匹配的产品名,按名称排序(可选)
            prod_names = Product.objects.filter(q_objects).values_list('name', flat=True).order_by('name')
            payload = list(prod_names)
    return JsonResponse({'status': 200, 'data': payload})

方案2:支持拼写错误的模糊匹配(基于PostgreSQL)

如果你的项目用PostgreSQL数据库,可以利用Trigram相似性来匹配拼写接近的内容,比如用户输入"Dispov"也能找到"DispoVan 10ml 21mg"。

步骤如下:

  1. 先安装依赖并配置:
    在settings.py的INSTALLED_APPS中添加django.contrib.postgres,然后运行迁移:

    python manage.py migrate
    
  2. 修改视图代码,结合关键词拆分和Trigram相似性:

from django.db.models import Q
from django.contrib.postgres.search import TrigramSimilarity

def search_address(request):
    query = request.GET.get('query', '')
    payload = []
    if query:
        keywords = [kw.strip() for kw in query.split() if kw.strip()]
        if keywords:
            # 先按关键词拆分匹配,再按Trigram相似性排序
            q_objects = Q()
            for kw in keywords:
                q_objects &= Q(name__icontains=kw)
            
            # 计算相似性,按相似性从高到低排序
            prod_results = Product.objects.filter(q_objects).annotate(
                similarity=TrigramSimilarity('name', query)
            ).filter(similarity__gt=0.1).order_by('-similarity')
            
            payload = list(prod_results.values_list('name', flat=True))
    return JsonResponse({'status': 200, 'data': payload})
  • 说明:similarity__gt=0.1是匹配阈值,值越高匹配越严格,可根据实际情况调整。

方案3:通用数据库的编辑距离匹配(兼容MySQL/SQLite)

如果不用PostgreSQL,可以用Levenshtein编辑距离算法(计算字符差异度,差异越小越相似),需要依赖第三方库实现。

  1. 安装依赖:
pip install django-levenshtein
  1. 在settings.py的INSTALLED_APPS中添加levenshtein。

  2. 修改视图代码:

from django.db.models import Q
from levenshtein.models import LevenshteinDistance

def search_address(request):
    query = request.GET.get('query', '')
    payload = []
    if query:
        keywords = [kw.strip() for kw in query.split() if kw.strip()]
        if keywords:
            q_objects = Q()
            for kw in keywords:
                q_objects &= Q(name__icontains=kw)
            
            # 计算编辑距离,按距离从小到大排序(距离越小越相似)
            prod_results = Product.objects.filter(q_objects).annotate(
                distance=LevenshteinDistance('name', query)
            ).filter(distance__lt=5).order_by('distance')
            
            payload = list(prod_results.values_list('name', flat=True))
    return JsonResponse({'status': 200, 'data': payload})
  • 说明:distance__lt=5表示编辑距离小于5,可根据需求调整阈值。

额外优化建议

  • 前端添加输入防抖,避免用户每输入一个字符就发起请求。
  • 缓存热门查询结果,减少数据库查询压力。
  • 对产品名做预处理(比如统一大小写、去掉冗余特殊字符),提升匹配准确率。

内容的提问来源于stack exchange,提问作者Rishi Goyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 23:24:54