关键字搜索django中的几个字段

时间:2013-12-16 16:02:14

标签: django

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

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

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

对此有任何简单的解决方案吗?

2 个答案:

答案 0 :(得分:1)

使用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
  • 我为firtcase创建了一个查询集
  • 然后我使用|
  • 将其加入到另一个反向选项的查询集中
  • 最后,我对该查询集进行了过滤,并使用了distinct来摆脱可能的重复

你可以添加更多逻辑。例如,'John A' - 姓氏显然是首字母缩略词,而不是整个名称,而第一个是全名。您可以实现一些处理它的逻辑并相应地构建查询集(containsstartswith更昂贵,或者然后进行简单的比较)。使用Q对象可以轻松实现。玩弄它,你会得到它的支持

答案 1 :(得分:-2)

我建议你使用natural_key。在您的用户模型中,添加如下内容:

def natural_key(self):
        return (self.first_name, self.last_name)

结果:

users = User.objects.filter()
for user in users:
    print(user.natural_key)

然后,您可以过滤自然键。

希望它有所帮助。