我正在使用 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' - 姓氏显然是首字母缩写词而不是全名,而名字是全名。您可以实现一些逻辑来处理这个问题并相应地构建查询集(contains
比 startswith
或简单比较更昂贵)。使用 Q 对象将使这变得容易。玩玩它,你会掌握它的窍门
关于django - 在 Django 中的多个字段上进行关键字搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20615235/