distinct() выбирает уникальные значения:
# без distinct people = Person.objects.values_list("name", flat=True) print(people) # <QuerySet ['Bob', 'Tom', 'Sam', 'Alice', 'Tom']> # с distinct people = Person.objects.values_list("name", flat=True).distinct() print(people) # <QuerySet ['Bob', 'Tom', 'Sam', 'Alice']>
В данном случае получаем набор из всех имен пользователей. Но во втором случае также добавляем метод distinct()
, который позволяет отсечь дубли.
Метод union() возвращает QuerySet, который является объединением двух QuerySet, что на уровне базы данных соответствует выполнению оператора UNION:
toms = Person.objects.filter(name="Tom") bobs = Person.objects.filter(name="Bob") # объединяем два QuerySet people = toms.union(bobs) print(people.values()) # <QuerySet [{'id': 1, 'name': 'Bob', 'age': 42}, {'id': 2, 'name': 'Tom', 'age': 38}, {'id': 5, 'name': 'Tom', 'age': 22}]>
По умолчанию метод union() выбирает только уникальные значения из обоих выборок. Если такое поведение нежелательно, то в метод необходимо передать аргумент
all=True
:
toms = Person.objects.filter(name="Tom") bobs = Person.objects.filter(name="Bob") # выбираем только уникальные (по умолчанию) people = toms.values("name").union(bobs) print(people) # <QuerySet [{'name': 'Bob'}, {'name': 'Tom'}]> # выбираем все people = toms.values("name").union(bobs, all=True) print(people) # <QuerySet [{'name': 'Tom'}, {'name': 'Tom'}, {'name': 'Bob'}]>
Метод может принимать несколько выборок, которые объединяются с первой выборкой.
Метод intersection() возвращает QuerySet в виде перечения других QuerySet (то есть находит объекты, которые есть во всех выборках). На уровне базы данных это будет соответствовать выполнению SQL-оператора
INTERSECT
:
toms = Person.objects.filter(name="Tom") print(toms.values()) # <QuerySet [{'id': 2, 'name': 'Tom', 'age': 38}, {'id': 5, 'name': 'Tom', 'age': 22}]> less35 = Person.objects.filter(age__lt=35) print(less35.values()) # <QuerySet [{'id': 3, 'name': 'Sam', 'age': 28}, {'id': 4, 'name': 'Alice', 'age': 32}, {'id': 5, 'name': 'Tom', 'age': 22}]> # находим пересечение двух QuerySet people = toms.intersection(less35) print(people.values()) # <QuerySet [{'id': 5, 'name': 'Tom', 'age': 22}]>
Метод может принимать несколько выборок, которые пересекаются с первой выборкой.
Метод difference() возвращает QuerySet в виде разности других QuerySet (то есть находит объекты, которые есть в первой выборке, но отсутствуют в других).
На уровне базы данных это будет соответствовать выполнению SQL-оператора EXCEPT
:
toms = Person.objects.filter(name="Tom") print(toms.values()) # <QuerySet [{'id': 2, 'name': 'Tom', 'age': 38}, {'id': 5, 'name': 'Tom', 'age': 22}]> less35 = Person.objects.filter(age__lt=35) print(less35.values()) # <QuerySet [{'id': 3, 'name': 'Sam', 'age': 28}, {'id': 4, 'name': 'Alice', 'age': 32}, {'id': 5, 'name': 'Tom', 'age': 22}]> # находим разность двух QuerySet people = toms.difference(less35) print(people.values()) # <QuerySet [{'id': 2, 'name': 'Tom', 'age': 38}]>
Метод может принимать множество выборок, которые надо вычесть из первой.