Подтвердить что ты не робот

Значок django с __in lookup

Итак, я хочу найти любое соответствие, соответствующее некоторым полям, так, например, это то, что я хотел бы сделать:

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

К сожалению, невозможно комбинировать значки и поиск __in.

Кажется, это довольно сложный запрос, так что, по крайней мере, я мог бы игнорировать случай, которого было бы достаточно, например:

Companies.objects.filter(name__ignorecase__in=possible_merchants)

Любые идеи?

P.D.: Запросы, которые я написал, не работают, это просто способ выразить то, что мне нужно (на всякий случай, хех)

4b9b3361

Ответ 1

Вы можете создать запрос с конструктором 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)

(И аналогично iexact вместо icontains.)

Ответ 2

Я считаю, это более чистый подход с использованием reduce и or_ оператора:

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 будут сведены к одному объекту Q имеющему несколько OR, которые могут быть непосредственно применены к запросу фильтра.

Ответ 3

Это подход, который я принял:

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

Он основан на наборе запросов фильтра Django __in для * каждого * элемента в списке и других предложениях в этой теме.

Вот теперь, чтобы использовать это:

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