在Django中查询全名

29 投票
7 回答
23875 浏览
提问于 2025-04-17 03:50

我想知道在Django中怎么查询全名。

简单来说,我想创建一个临时的列,把名字(first_name)和姓氏(last_name)合并成一个全名(fullname),然后在这个全名上进行模糊查询,比如这样:

select [fields] from Users where CONCAT(first_name, ' ', last_name) LIKE '%John Smith%";

上面的查询会返回所有名叫John Smith的用户。如果可以的话,我希望避免使用原始的SQL语句。

我说的这个模型是Django自带的用户模型django.contrib.auth.models User。直接修改这个模型是没问题的。

举个例子,如果用户搜索'John Paul Smith',那么应该能匹配到名字是'John Paul'、姓氏是'Smith'的用户,也能匹配到名字是'John'、姓氏是'Paul Smith'的用户。

7 个回答

13

更简单:

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

这里的query_name可以是“John Smith”(但如果有的话,也会找到用户Smith John)。

64

这个问题早就被提出来了,但我遇到过类似的问题,发现这里的答案都不太好。被接受的答案只能通过名字和姓氏完全匹配来查找。第二个答案稍微好一点,但还是不够,因为每个单词都会去查询数据库,效率很低。

我的解决方案是把名字和姓氏连接在一起,然后在这个字段里进行搜索:

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

users = User.objects.annotate(full_name=Concat('first_name', V(' '), 'last_name')).\
                filter(full_name__icontains=query)

比如说,如果这个人的名字是约翰·史密斯,你可以通过输入约翰·史密斯、约翰、史密斯、hn smi等等来找到他。这样只会查询一次数据库。我觉得这就是你在帖子中想要的SQL查询。

3

如果我没理解错的话,你可以用Python来查询你的数据库,像这样:

from django.contrib.auth.models import User
x = User.objects.filter(first_name='John', last_name='Smith') 

补充:为了回答你的问题:

如果你希望用户搜索'John Smith'时能返回'John Paul Smith',那么你可以使用'contains',这个在SQL中相当于LIKE。如果你只是想存储名字'John Paul',那么可以把两个名字都放在first_name这一列里。

User.objects.filter(first_name__contains='John', last_name__contains='Smith') 

这可以转化为:

SELECT * FROM USERS
WHERE first_name LIKE'%John%' 
AND last_name LIKE'%Smith%'

撰写回答