【问题标题】:Search for multiple搜索多个
【发布时间】:2010-12-12 01:55:08
【问题描述】:

我的搜索功能通过以下任一方式接收搜索词:

  • first_name“托马斯”
  • 姓氏“史密斯”
  • first_name last_name "thomas smith"

我正在尝试构建一个查询集,该查询集将通过任何这些术语找到客户端“thomas”,但如果两个名称都将结果缩小为“thomas smith”而不是“thomas jones”或“george smith”提供。

我已经对如何使用过滤器、Q 对象、字符串拆分和 for 循环来完成此任务进行了大量研究,但到目前为止还没有运气。

MODEL:
class Client(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

VIEW:
def search(request):
    query = request.GET.get('s', '').strip()
    if query:
        client_set = (
            (Q(first_name__in=query) & Q(last_name__in=query)) |
            Q(first_name__icontains=query) |
            Q(last_name__icontains=query)  
        )
    else:
        client_list = []
    return render_to_response("search.html", {
        "client_list": client_list,
        "query": query
    },context_instance=RequestContext(request))

上面的代码在搜索“thom”时有效,但没有找到“thomas smith”。我怎样才能重写它以按照描述的方式运行?

【问题讨论】:

  • 您使用first_name__in 而不是first_name__icontains 有什么具体原因吗?因为我很确定__in 不会按照您期望的方式工作;)
  • 我也用 __icontains 试过了。我对 __in 的理解是它应该在 SQL 级别转换为 LIKE。虽然我的 SQL 生锈了,但我希望这意味着它将获取搜索查询的任何部分并将其与字段值匹配,以便“thomas smith”将匹配名字中的“thomas”,然后匹配“smith”姓氏。如果它确实以这种方式工作,我认为我的查询会起作用。显然不是。 :-)
  • __contains 运算符将转换为 LIKE__icontains 将转换为 ILIKE__in 通常用于主键查找,并将转换为 id IN (...)

标签: django


【解决方案1】:

我相信这应该做你想做的:

def search(request):
    name = request.GET.get('s', '').strip().split(' ', 1)
    client_set = Client.objects.all()

    if len(name) == 2:
        first_name, last_name = name
        client_set = client_set.filter(
            first_name__icontains=first_name,
            last_name__icontains=last_name,
        )
    else:
        name = name[0]
        client_set = client_set.filter(
            client_set.filter(first_name__icontains=name)
            | client_set.filter(last_name__icontains=name)
        )

    return render_to_response("search.html", {
        "client_list": client_list,
        "query": query
    }, context_instance=RequestContext(request))

【讨论】:

  • 'if else' 条件下的 client_set 不应该是 client_list 吗?
  • 感谢您提供此代码。看起来它会完全满足我的需要。我没有想到只搜索一个恰好有 2 个名称的条件,然后以这种方式处理。在我有时间处理这个项目并实施这个项目后,我会再次回来发表评论。再次感谢您!
  • 感谢您的帮助。我为此使用了 Q 对象,但是您分别处理 2 个字符串的想法非常有帮助。我试图变得更复杂并允许 x 字符串。但这不是必需的。
  • @Antientropic:很高兴我能帮上忙 :)
猜你喜欢
  • 2021-05-01
  • 1970-01-01
  • 2020-08-23
  • 2014-07-31
  • 2018-01-08
  • 1970-01-01
相关资源
最近更新 更多