【问题标题】:django icontains with __in lookup带有 __in 查找的 django 图标
【发布时间】:2012-03-29 07:15:17
【问题描述】:

所以我想在给定一些字段的情况下找到任何类型的匹配,例如,这就是我想做的:

possible_merchants = ["amazon", "web", "services"]
# Possible name --> "Amazon Service"
Companies.objects.filter(name__icontains__in=possible_merchants)

遗憾的是,无法混合使用 icontains 和 __in 查找。

这似乎是一个相当复杂的查询,所以如果至少我可以忽略名称就足够了,例如:

Companies.objects.filter(name__ignorecase__in=possible_merchants)

有什么想法吗?

PD:我发布的查询不起作用,这只是表达我需要的一种方式(以防万一)

【问题讨论】:

标签: django


【解决方案1】:

您可以创建查询集with the Q constructor 并将它们与| 运算符组合以获得它们的联合:

from django.db.models import Q

def companies_matching(merchants):
    """
    Return a queryset for companies whose names contain case-insensitive
    matches for any of the `merchants`.
    """
    q = Q()
    for merchant in merchants:
        q |= Q(name__icontains = merchant)
    return Companies.objects.filter(q)

(同样使用iexact 而不是icontains。)

【讨论】:

  • 如果有人需要动态字段名,请使用q |= Q(**{'%s__icontains' % field_name: merchant})
【解决方案2】:

我发现使用reduceor_ 运算符是一种更简洁的方法:

from django.db.models import Q
from functools import reduce
from operator import or_

def get_companies_from_merchants(merchant_list):
    q_object = reduce(or_, (Q(name__icontains=merchant) for merchant in merchant_list))
    return Companies.objects.filter(q_object)

这将创建一个Q 对象列表,查询name 以包含商家列表中的单个元素。 merchant_list 中的所有元素都会发生这种情况,所有这些 Q 对象将被简化为具有多个 OR 的单个 Q 对象,可以直接应用于过滤器查询。

【讨论】:

    【解决方案3】:

    这是我采用的方法:

    class MyManager(models.Manager):
        def exclusive_in(self, lookup, value_list):
            return self.filter(reduce(or_, (Q(**{lookup:_}) for _ in value_list)))
    

    现在可以使用它了:

    Companies.objects.exclusive_in('name__icontains', possible_merchants])
    

    受此线程中其他答案以及Django filter queryset __in for *every* item in list 的启发。

    【讨论】:

      【解决方案4】:

      另一种方法是模拟 Django 通常对 iexact 查询执行的操作(它通过 SQL Upper 函数将比较语句的两个部分都转换为大写。

      这样,查询将如下所示:

      Companies.objects.annotate(
          upper_name=models.Upper("name")
      ).filter(
          upper_name__in=[rchant.upper() for merchant in possible_merchants]
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-09
        • 2013-08-03
        • 1970-01-01
        • 2011-11-13
        • 2011-07-01
        • 2015-12-30
        • 2013-02-28
        • 2018-02-17
        相关资源
        最近更新 更多