【问题标题】:Django queryset searching for firstname and lastname with startswithDjango查询集搜索名字和姓氏与startswith
【发布时间】:2021-12-28 05:49:54
【问题描述】:

我有一个 django 应用程序,我在其中从 first_name 和 last_name 搜索名称。 使用 Q 标签对我有用。

from django.db.models import Q 

def find_user_by_name(query_name):
   qs = User.objects.all()
   for term in query_name.split():
     qs = qs.filter( Q(first_name__icontains = term) | Q(last_name__icontains = term))
   return qs

但我遇到了一个问题,即订购的数据不是我想要的。

例如:search_word = 'Kia' 我搜索后得到的结果是:

        {
            "first_name": "Katja",
            "last_name": "Tukiainen", 
        },
        {
            "first_name": "Kia",
            "last_name": "Reijonen",
        },
        {
            "first_name": "Sanna",
            "last_name": "Kiander",
        }
    ]

但我想要一个首先以 Kia 开头的结果,结果如下:

        {
            "first_name": "Kia",
            "last_name": "Reijonen",
        },
        {
            "first_name": "Katja",
            "last_name": "Tukiainen",
            
        },
        {
            "first_name": "Sanna",
            "last_name": "Kiander",
        }
    ]

请帮助我解决这个问题,我尝试使用 startswith 进行此操作,但不适用于我。 提前致谢。

【问题讨论】:

    标签: python-3.x django django-views


    【解决方案1】:

    首先你必须在 django 全文搜索中进行 RND,但现在试试这个。

    添加

    "django.contrib.postgres",

    到 settings.py 中的 INSTALLED_APPS

    然后使用以下搜索向量和搜索排名

        vector = SearchVector('first_name', weight='A') + SearchVector('last_name', weight='B')
        query = SearchQuery('Kia')
        users =User.objects.annotate(rank=SearchRank(vector, query)). \
            filter(Q(last_name__icontains='Kia') | Q(first_name__icontains='Kia')).order_by('-rank')
    

    记得导入

    from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
    

    祝你好运!

    【讨论】:

      【解决方案2】:

      您可以使用.union(…) [Django-doc]

      def find_user_by_name(query_name):
          qs = User.objects.all()
          q1 = Q(*[
              Q(('first_name__istartswith', term)) | Q(('last_name__istartswith', term))
              for term in query_name.split()
          ])
          q2 = Q(*[
              Q(('first_name__icontains', term)) | Q(('last_name__icontains', term))
              for term in query_name.split()
          ])
          return qs.filter(q1).union(qs.filter(q2))

      【讨论】:

      • 感谢您回答我,但它会给出 ValueError 的错误。 ValueError:要解压的值太多(预期为 2)
      • @AbhishekDubey:缺少一对括号。
      • 谢谢,@willem van onsem 它为我工作。
      • 我们可以添加两个带startswith的字段吗? stackoverflow.com/questions/70751460/…
      猜你喜欢
      • 2012-02-19
      • 2023-03-19
      • 1970-01-01
      • 2011-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      相关资源
      最近更新 更多