Простой способ для объединения и вычитания QuerySet в Django?

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

6 ответов

Начиная с 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 | а также & и дополнительно оператор инверсии ~

Вычтите 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/

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

new_query_set = query_set_1 | query_set_2

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

new_query_set = query_set_1 & query_set_2

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

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

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

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

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

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

      qs3 = qs1.union(qs2) # union
qs4 = qs1.difference(qs2) # subtraction

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

Другие вопросы по тегам