Простой способ для объединения и вычитания 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:
Возвращаясь к документации 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!