Оператор Django In в Python — использование и примеры

Оператор Django In используется в Python для проверки наличия значения в наборе значений.

Содержание

Введение в Django In

Для демонстрации мы будем использовать модель Employee в приложении HR. Модель Employee сопоставляется с таблицей hr_employee в базе данных:

Знакомство с Django In

Оператор 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))

 

Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *