Оператор Django In в Python — использование и примеры
Оператор Django In используется в Python для проверки наличия значения в наборе значений.
Введение в Django In
Для демонстрации мы будем использовать модель Employee в приложении HR. Модель Employee сопоставляется с таблицей hr_employee в базе данных:
Оператор SQL IN возвращает значение true, если значение входит в набор значений:
field_name IN(v1, v2, ...)
Например, вы можете использовать оператор IN для запроса строк из таблицы hr_employee, department_id которых находится в списке следующим образом:
SELECT * FROM hr_employee WHERE department_id IN(1,2,3)
В Django используется оператор in:
>>> Employee.objects.filter(department_id__in=(1,2,3)) SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" WHERE "hr_employee"."department_id" IN(1, 2, 3)
Обычно вы используете подзапрос с оператором in, а не список литеральных значений. Например, вы находите всех сотрудников в отделах продаж и маркетинга следующим образом:
>>> departments = Department.objects.filter(Q(name='Sales') | Q(name='Marketing')) >>> Employee.objects.filter(department__in=departments) SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" WHERE "hr_employee"."department_id" IN( SELECT U0."id" FROM "hr_department" U0 WHERE(U0."name" = 'Sales' OR U0."name" = 'Marketing') )
Как это работает.
- Сначала найдите отделы с названиями «Sales» или «Marketing»:
departments = Department.objects.filter(Q(name='Sales') | Q(name='Marketing'))
- Во-вторых, передайте QuerySet отдела оператору in:
Employee.objects.filter(department__in=departments)
За кулисами Django выполняет запрос с оператором IN, который сопоставляет идентификатор отдела со списком идентификаторов отделов из списка:
SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" WHERE "hr_employee"."department_id" IN( SELECT U0."id" FROM "hr_department" U0 WHERE(U0."name" = 'Sales' OR U0."name" = 'Marketing') )
NOT IN
Оператор NOT отрицает оператор IN. Оператор NOT IN возвращает true, если значение отсутствует в списке значений:
field_name NOT IN(v1, v2, ...)
Для выполнения NOT IN в Django можно использовать объект Q и оператор ~:
~Q(field_name__in=(v1,v2,..))
Например, следующий код находит сотрудников, идентификатор отдела которых не равен 1, 2 или 3:
>>> Employee.objects.filter(~Q(department_id__in=(1,2,3))) SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" WHERE NOT("hr_employee"."department_id" IN(1, 2, 3))
В качестве альтернативы вы можете использовать метод exclude() вместо метода filter():
>>> Employee.objects.exclude(department_id__in=(1,2,3)) SELECT "hr_employee"."id", "hr_employee"."first_name", "hr_employee"."last_name", "hr_employee"."contact_id", "hr_employee"."department_id" FROM "hr_employee" WHERE NOT("hr_employee"."department_id" IN(1, 2, 3))
Заключение
- Используйте Django для проверки наличия значения в списке значений.
Django ORM | SQL |
---|---|
Entity.objects.filter(id__in=(v1,v2,v3) | id IN (v1,v2,v3) |
Entity.objects.filter(~Q(id__in=(v1,v2,v3)) | NOT (id IN (v1,v2,v3)) |
Entity.objects.exclude(id__in=(v1,v2,v3) | NOT (id IN (v1,v2,v3)) |