使用__in查找django icontains

Has*_*sek 15 python django

所以我想在某些字段中找到任何类型的匹配,例如,这就是我想要做的:

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

遗憾的是,无法混合icontains和__in查找.

它似乎是一个非常复杂的查询,所以如果至少我可以忽略大小足够的名称,例如:

Companies.objects.filter(name__ignorecase__in=possible_merchants)
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

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

Gar*_*ees 26

您可以使用Q构造函数创建查询集,并将它们与|运算符组合以获取它们的联合:

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)
Run Code Online (Sandbox Code Playgroud)

(与之相似iexact而不是icontains.)

  • 如果有人需要这个动态字段名称,请使用`q | = Q(**{'%s__icontains'%field_name:merchant}) (5认同)

San*_*ana 5

我发现使用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)
Run Code Online (Sandbox Code Playgroud)

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