Объединение нескольких наборов результатов Django - PullRequest
0 голосов
/ 09 января 2012

У меня есть 2 модели django:

class Foo(models.Model):
    baz = models.CharField()

class Bar(models.Model);
    foo = models.ForeignKey(Foo)
    qux = models.CharField()

со следующими данными:

Foo
id baz
4  X
5  Y
6  Z

Bar
id foo_id qux
1  4      A
2  5      A
3  5      B
4  6      B

теперь я делаю 2 запроса на Bar, отфильтрованных на qux:

resA = [1, 2] (actually bar instances; shown bar.id for convenience)
resB = [3, 4] (actually bar instances; shown bar.id for convenience)

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

resAND = [5] (foo.id)

Сейчас я делаю:

ret = []
nr_sets = 2
foos = Foo.objects.all()
bars = list(resA + resB)
for foo in foos:
    test = filter(lambda bar : bar.foo_id == foo.id, bars)
    if test == nr_sets;
        ret.append(foo)

Это, однако, ужасно медленно.Любые идеи в ускорении этого?Я особенно ищу решения после запроса, но хорошие идеи относительно запросов также приветствуются.

Ответы [ 2 ]

1 голос
/ 09 января 2012

Вы можете попробовать

foo_ids = set(resA.values_list('foo_id', flat=True)) & \
    set(resB.values_list('foo_id', flat=True))

Тогда вы можете получить соответствующие полные Foo объекты с

ret = Foo.objects.in_bulk(foo_ids).values()

Редактировать : использовано set, потому что, по-видимому& не работает должным образом на ValueQuerySet.

0 голосов
/ 09 января 2012

Почему бы и нет:

Bar.objects.filter(foo__id=5)

Вы также можете добавить туда другие параметры фильтра, они будут по умолчанию AND'ами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...