простой способ для объединения и вычитания QuerySet в Django? - PullRequest
17 голосов
/ 04 июня 2010

Рассмотрим два объекта QuerySet одного класса. Есть ли простой способ объединить их в один QuerySet путем расчета объединения? Кроме того, есть ли простой способ вычесть их? Удалить все элементы, которые появляются в обоих наборах из одного набора?

Ответы [ 5 ]

13 голосов
/ 25 января 2012

Вычтите QuerySet из другого QuerySet, используя ту же модель.

Это работает - но, вероятно, медленно

queryset_with_hello = Blog.objects.filter(name__icontains='hello')
queryset_without_hello = Blog.objects.exclude(pk__in=queryset_with_hello)

Ознакомьтесь с рекомендациями по производительности в документации django:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#in

13 голосов
/ 04 июня 2010

Возвращаясь к документации django , вы можете:

new_query_set = query_set_1 | query_set_2

Это работает как логическое ИЛИ, которое фактически является дополнением без дубликатов.Это отвечает аспекту сложения, и AFAIK вообще не попадает в БД !

new_query_set = query_set_1 & query_set_2

Это работает как логическое AND.

Все еще отсутствует способ вычитания QuerySets.Мне трудно поверить, что сообщество не решило этого элегантно ...

9 голосов
/ 12 августа 2017

Начиная с Django 1.11, QuerySets имеет методы union(), intersection() и difference().

Также возможно использовать | и & операторы с QuerySets (я не могу найти ссылку на это в документации, поэтому я думаю, union() и intersection() предпочтительнее способ объединить два набора запросов.

qs3 = qs1.union(qs2)         # or qs3 = qs1 | qs2
qs3 = qs1.intersection(qs2)  # or qs3 = qs1 & qs2
qs3 = qs1.difference(qs2)    # the ^ operator is not implemented.

Вы также можете использовать Q() объекты , которые подобно QuerySets реализуют | и &, и дополнительно оператор инверсии ~

3 голосов
/ 04 июня 2010

Вы можете использовать Q объект .

Синтаксис может быть примерно таким:

added_query_set = YourModel.objects.\
         filter(Q(id__in=old_query_set_1)|Q(id__in=old_query_set_2))

Вы, вероятно, можете оптимизировать на основе ваших реальных потребностей и уменьшить количество попаданий в дб (сейчас это 3), но это должно помочь вам начать.

0 голосов
/ 04 июня 2010

Я думаю, что для операций, как это вам нужно оценить их. Таким образом, вы можете вызывать list() для них и работать с ними с помощью общих операций со списком Python!

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