django - 在 Django 中的多个字段上进行关键字搜索

标签 django

我正在使用 django 的标准用户模型。

我想按名字和姓氏搜索用户。所以我有一个自由文本搜索并使用 icontains 我正在搜索该文本。

但是,我希望用户可以搜索“John A”并检索其名字+姓氏包含“John A”的所有用户,但是,因为我在名字和姓氏上分别使用 icontains,它不起作用。 “约翰”一个人就可以了。但只要我涉及这两个领域,它就没有(这是有道理的)

有什么简单的解决方案吗?

最佳答案

使用 Q 对象创建查询,使用 | 表示 OR,使用 & 表示 AND。

>>> from django.db.models import Q
>>> qs = Q(first_name__icontains='John A') | Q(last_name__icontains='John A')
>>> User.objects.filter(qs)

了解更多 here

p.s.您还可以使用|& 加入常规查询集

User.objects.filter(...) | User.objects.filter(...)

但我认为在遍历多个字段时使用 Q 对象会更整洁

编辑

作为您的评论,您要做的就是:

>>> query = 'John A'
>>> fn, ln = query.split()
>>> User.objects.filter(first_name=fn, last_name=ln)

对于复杂的情况,您可能需要检查名字和姓氏。第二个通常是中间名或其他人的一部分,因此 icontain 会捕获它。所以像这样:

>>> query = 'Jon Van Mendrik'
>>> fn, ln = [i[0], i[-1] for i in query.split()] #take the first and last
>>> print fn, ln
"Jon Mendrik"
>>> qs = Q(first_name__icontains=fn, last_name__icontains=ln)
>>> qs = qs | Q(first_name__icontains=ln, last_name__icontains=fn)
>>> User.objects.filter(qs).distinct()

它不是很漂亮,但可能适用于大多数情况,包括首先输入姓氏等。只要确保你理解我在这里所做的,而不是盲目地将其复制到你的项目中 -

  • 我把字符串的第一部分和最后部分分别赋给了fn和ln
  • 我为第一个案例创建了一个查询集
  • 然后我使用 |
  • 将它加入另一个查询集以获得反向选项
  • 最后,我对该查询集进行了过滤,并使用 distinct 来去除可能的重复项

您可能可以添加更多逻辑。例如,'John A' - 姓氏显然是首字母缩写词而不是全名,而名字是全名。您可以实现一些逻辑来处理这个问题并相应地构建查询集(containsstartswith 或简单比较更昂贵)。使用 Q 对象将使这变得容易。玩玩它,你会掌握它的窍门

关于django - 在 Django 中的多个字段上进行关键字搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20615235/

相关文章:

python - 在geodjango中按距离排序效率如何(整张表)

python - Pycharm 3 调试器不适用于 Django

python - 如何使用 CircleCI 在后台运行服务器?

python - 在迁移文件中正确声明空 Django PostgreSQL JSONField 默认值

python - 权限 : in django rest framework

Django:在测试期间从 STATIC_ROOT 读取

python - 构建处理 redis 和 cache_method 装饰器的测试

python - 如何在接收模型端明确显示 Django ManyToMany 关系

python - Django:优化多对多查询

python - django-rest-framework:在 ViewSet 更新方法中添加额外的权限