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

Django QuerySet姓名搜索按startswith前缀优先排序问题

解决方案

你可以通过Django的annotate结合条件表达式给不同匹配规则分配权重,再按权重降序排序即可实现需求,具体修改如下:

完整代码

from django.db.models import Q, Case, When, Value, IntegerField

def find_user_by_name(query_name):
    qs = User.objects.all()
    terms = query_name.split()
    # 保留原有过滤逻辑,筛选出所有包含关键词的结果
    for term in terms:
        qs = qs.filter(Q(first_name__icontains=term) | Q(last_name__icontains=term))
    
    # 构造权重计算规则
    weight_rules = []
    for term in terms:
        # 名以关键词开头加10分
        weight_rules.append(When(first_name__istartswith=term, then=Value(10)))
        # 姓以关键词开头加10分
        weight_rules.append(When(last_name__istartswith=term, then=Value(10)))
    
    # 给每个结果注解匹配权重,按权重倒序排列
    qs = qs.annotate(
        match_weight=Case(
            *weight_rules,
            default=Value(0),
            output_field=IntegerField()
        )
    ).order_by('-match_weight')
    # 如果权重相同需要补充排序规则,可在order_by里追加字段,比如:.order_by('-match_weight', 'first_name', 'last_name')
    
    return qs

逻辑说明

  • 用istartswith做大小写不敏感的开头匹配,避免大小写问题导致权重计算错误
  • 开头匹配的条目权重远高于仅包含关键词的条目,排序时会自动排在最前面,完全符合你预期的排序规则
  • 如果需要更精细的排序优先级,比如名开头匹配比姓开头匹配优先级更高,可以把两个When的权重值设为不同数值即可,比如名开头加20分、姓开头加10分

内容的提问来源于stack exchange,提问作者Abhishek Dubey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:06:03