Django - получить список предметов с фильтром - PullRequest
1 голос
/ 06 мая 2011

Мои модели:

Item:
    name
    desc

Type:
    name

Value:
    text
    type.ForeignKey(Type)
    item = ForeignKey(Item)

У меня был начальный список типов из таблицы Тип, предположим, что t = [4,5,6].Теперь я должен получить список предметов, которые имеют типы т.Например:

Список данных значения:

type  |  item
4        1
5        1
6        1
4        2
5        2
4        3

Итак, если t = [4,5,6], мне нужен результат, равный items = [<object: 1>]

ОБНОВЛЕНИЕ :

t = [4,5] items = [<object: 1>, <object: 2>]

t = [4] items = [<object: 1>, <object: 2>, <object: 3>]

Спасибо за любую помощь !!!

Ответы [ 2 ]

2 голосов
/ 06 мая 2011

Не совсем уверен, что это лучшее решение, но оно работает

from itertools import groupby

values = Value.objects.filter(type_id__in=t).values_list('type_id', 'item_id')
values = sorted(values, key=lambda x: x[1])

items = []
for key, group in groupby(values, lambda x: x[1]):
    types = [x[0] for x in group]
    if set(t).issubset(set(types)):
        items.append(key)

items будет содержать идентификаторы, а не объекты, но я не думаю, что это может быть проблемой.

1 голос
/ 06 мая 2011

Вы можете отфильтровать отношение «многие ко многим», значение которого равно:

Item.objects.filter(value__type__id__in = [4, 5, 6])

Обновление: вышеописанное будет работать для запроса ИЛИ, чтобы найти все элементы, которые имеют ЛЮБОЙ из указанных типов. Чтобы найти все элементы, которые имеют ВСЕ типы, необходимо создать запрос AND с помощью цепочек фильтров:

q = Item.objects
for id in [4, 5, 6]:
    q = q.filter(value__type__id = id)
print q.all()
# or
q = reduce(lambda q, i: q.filter(value__type__id = i), [4, 5, 6], Item.objects)
print q.all()
...