【问题标题】:Django search objects by multiple keysDjango 通过多个键搜索对象
【发布时间】:2014-04-09 18:34:38
【问题描述】:

我正在尝试准备搜索表单,用户可以在其中输入 1、2 或所有(在本例中为 3 个)搜索过滤器。

假设搜索过滤器是: 姓氏、电话和地址。我正在尝试通过以下方式过滤查询集:

if filterForm.is_valid():
    last_name = filterForm.cleaned_data.get('last_name')
    phone= filterForm.cleaned_data.get('phone')
    address = filterForm.cleaned_data.get('address')

    if last_name is None and phone is None and address is None:
        pass
        #we dont do search id db
    else:
        clients = Client.objects.filter(Q(last_name__contains=last_name) | Q(phone=phone) | Q(address__contains=address))

每个搜索键都可以为空。

不幸的是,它返回的结果比预期的要多。当我输入搜索过滤器“示例”作为姓氏字段时,它会返回具有此姓氏的所有字段+许多其他行。

知道如何解决这个搜索问题吗?

【问题讨论】:

    标签: django django-models django-queryset django-orm


    【解决方案1】:

    我相信当任何搜索键为空白时,您的搜索返回的结果比预期的要多,因为空白键将匹配任何具有值的行。

    只过滤包含值的键应该会更好。

    下面是一个例子:

    if filterForm.is_valid():
        last_name = filterForm.cleaned_data.get('last_name')
        phone= filterForm.cleaned_data.get('phone')
        address = filterForm.cleaned_data.get('address')
    
        import operator
    
        predicates = []
    
        if last_name:
            predicates.append(Q(last_name__contains=last_name))
        if phone:
            predicates.append(Q(phone=phone))
        if address:
            predicates.append(Q(address__contains=address))
    
        if len(predicates) == 0:
            # Nothing to search for
            pass
        else:
            clients = Client.objects.filter(reduce(operator.or_, predicates))
    

    上面的代码将动态添加过滤器,这些过滤器将被添加到查询中。 oprator.or_ 的使用会将语句与OR 连接起来(=至少需要满足一个语句)。如果您希望所有语句都得到满足,您可以改用operator.and_。

    【讨论】:

      猜你喜欢
      • 2017-07-17
      • 2015-05-01
      • 1970-01-01
      • 2019-01-18
      • 2017-04-22
      • 1970-01-01
      • 2018-02-18
      • 2021-05-26
      • 1970-01-01
      相关资源
      最近更新 更多