在Django中查询全名
我想知道在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 个回答
更简单:
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)。
这个问题早就被提出来了,但我遇到过类似的问题,发现这里的答案都不太好。被接受的答案只能通过名字和姓氏完全匹配来查找。第二个答案稍微好一点,但还是不够,因为每个单词都会去查询数据库,效率很低。
我的解决方案是把名字和姓氏连接在一起,然后在这个字段里进行搜索:
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查询。
如果我没理解错的话,你可以用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%'