我正在使用django的标准用户模型。
我想按名字和姓氏搜索用户。所以我有一个自由文本搜索和使用icontains我正在搜索该文本。
但是,我希望用户可以搜索“John A”并检索他们的名字+姓氏包含“John A”的所有用户,但是因为我在名字和姓氏上分别使用了icontains,所以不起作用。只有“约翰”才能奏效。但只要我涉及两个领域,它就没有(这是有意义的)
对此有任何简单的解决方案吗?
答案 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()
它不是很漂亮,但可能适用于大多数情况,包括首先输入姓氏的位置,依此类推。只要确保你理解我在这里做了什么,而不是盲目地将它复制到你的项目 -
|
你可以添加更多逻辑。例如,'John A' - 姓氏显然是首字母缩略词,而不是整个名称,而第一个是全名。您可以实现一些处理它的逻辑并相应地构建查询集(contains
比startswith
更昂贵,或者然后进行简单的比较)。使用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)
然后,您可以过滤自然键。
希望它有所帮助。