在Django中搜索姓名

时间:2019-03-27 22:54:18

标签: python django

我在Django上有这个模型:

class Profile(models.Model):
  name = models.CharField(max_length=50, blank = False)
  surname = models.CharField(max_length=100, blank = False)
  ...

例如,我在数据库中有2个配置文件:

  • John Doe
  • 约翰·史密斯

我想进行一次表单搜索,同时搜索名称和姓氏属性。

我尝试过:

Q(name__icontains=text) | Q(surname__icontains=text)

但是这不起作用,例如,如果我搜索“ John Doe”,它将返回它们两者。

修改: 基本上我想要的是类似“加入”名称和姓氏属性的搜索,因此当我搜索“ John”时,它会显示“ John Doe”和“ John Smith”,而当我搜索“ John Doe”时,它将显示我仅“ John Doe”个人资料。

2 个答案:

答案 0 :(得分:2)

尝试一下

from django.db.models import Value as V
from django.db.models.functions import Concat

text = "John Doe"
Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)

参考

  1. Concat DB fucntion
  2. Django queryset filter after a concatenation of two columns

Django shell输出

In [14]: from django.db.models import Value as V                                                                                                                                                                   

In [15]: from django.db.models.functions import Concat                                                                                                                                                             

In [16]: text = "John Doe"                                                                                                                                                                                         

In [17]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[17]: <QuerySet [<Profile: John Doe>]>

In [18]: text = "john"                                                                                                                                                                                             

In [19]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[19]: <QuerySet [<Profile: John Doe>, <Profile: John Smith>]>

In [20]: text="smith"                                                                                                                                                                                              

In [21]: Profile.objects.annotate(full_name=Concat('name', V(' '), 'surname')).filter(full_name__icontains=text)                                                                                                   
Out[21]: <QuerySet [<Profile: John Smith>]>

答案 1 :(得分:1)

这是来自this answer的修改后的副本/粘贴。

我试图提出各种方法,但是它们都需要在每次查询后对行进行计数,这确实很耗时。相反,最好的方法似乎是用空格将文本分割并对其应用过滤器:

$cat = $category->with(['events' => function ($q) {
       $q->where('approved', 1);
    }]
)->get();