Sta*_*ute 1 django django-queryset django-q
我正在实现搜索功能,并可以选择通过匹配多个表和这些表中的多个字段来查找记录。
Customer假设我想通过他/她的名字或姓氏,或者通过存储Order在与 不同模型中的放置 ID 来查找Customer。我已经实现的简单场景是用户仅在搜索字段中输入单个单词,然后我使用 Django使用直接字段引用或类似引用Q来查询模型:Orderrelated_query_name
result = Order.objects.filter(
Q(customer__first_name__icontains=user_input)
|Q(customer__last_name__icontains=user_input)
|Q(order_id__icontains=user_input)
).distinct()
Run Code Online (Sandbox Code Playgroud)
小菜一碟,完全没有问题。
但是,如果用户想要缩小搜索范围并在搜索字段中输入多个单词该怎么办?
示例:用户输入Bruce并通过搜索返回大量记录。
现在他/她想要更具体,并将客户的姓氏添加到搜索中。因此Bruce Wayne,在将其分成我拥有的单独部分之后,搜索Bruce变为 和Wayne。显然,我不想搜索Orders模型,因为order_id它是一个单词实例,并且足以立即找到客户,因此对于这种情况,我完全将其从查询中删除。
现在我试图通过名字和姓氏来匹配客户,我还想处理提供数据的顺序是随机的情况,以正确处理Bruce Wayne和Wayne Bruce,这意味着我仍然有客户的全名,但名字和姓氏的位置名字不固定。
这就是我正在寻找答案的问题:如何构建查询来搜索模型的多个字段,而不知道哪些搜索词属于哪个表。
我猜这个解决方案很简单,并且肯定有一种优雅的方法来创建这样的动态查询,但我想不出一种方法。
您可以动态地将可变数量的 Q 对象组合在一起以实现所需的搜索。使用下面的方法可以轻松添加或删除要包含在搜索中的字段。
from functools import reduce
from operator import or_
fields = (
'customer__first_name__icontains',
'customer__last_name__icontains',
'order_id__icontains'
)
parts = []
terms = ["Bruce", "Wayne"] # produce this from your search input field
for term in terms:
for field in fields:
parts.append(Q(**{field: term}))
query = reduce(or_, parts)
result = Order.objects.filter(query).distinct()
Run Code Online (Sandbox Code Playgroud)
使用reduce通过 ORing 将 Q 对象组合在一起。这部分答案归功于此答案。
| 归档时间: |
|
| 查看次数: |
1911 次 |
| 最近记录: |