Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

2.9 Q-объекты и F-объекты
2 из 2 шагов пройдено

Выражения Q() инкапсулирует SQL выражение внутри объекта Python. Объекты Q() наиболее часто используются для построения сложных запросов к базе данных, связывая вместе несколько выражений, используя операторы AND & и OR |:

Например с помощью следующего запроса, мы можем получить всех сотрудников, имена которых начинаются на "Ja" или "Jo".

Employee.objects.filter(Q(first_name__startswith='Ja') | Q(first_name__startswith='Jo'))

В Django вы можете использовать объект Q с диапазоном, чтобы проверить, не находится ли значение в диапазоне, для этого вы можете использовать Q объект и ~ оператор:

Entity.objects.filter(~Q(field_name__range=(low_value,high_value)))

Например, вы можете найти сотрудников с идентификатором, не входящим в диапазон (3,5):

Employee.objects.filter(~Q(id__range=(3,5)))

Обычно вы используете подзапрос с in оператором, а не список литеральных значений. Например, вы найдете всех сотрудников в отделах IT и Testing следующим образом:

departments = Department.objects.filter(Q(name='IT') | Q(name='Testing')) 
Employee.objects.filter(department__in=departments)

Как это работает.

Сначала  мы получаем отделы с именами IT или Testing:

departments = Department.objects.filter(Q(name='IT') | Q(name='Testing'))

Далее мы передаем department 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" = 'IT' OR U0."name" = 'Testing')
       )

 

Оператор NOT отрицает IN оператор. Оператор NOT IN возвращает True, если значение отсутствует в списке значений:

field_name NOT IN (v1, v2, ...)

Для выполнения NOT IN в Django вы можете использовать Q объект и ~ оператор:

~Q(field_name__in=(v1,v2,..))

Например, следующий код находит сотрудников, чей идентификатор отдела не равен 2 или 3:

Employee.objects.filter(~Q(department_id__in=(2,3)))

В качестве альтернативы вы можете использовать exclude() метод вместо filter() метода:

Employee.objects.exclude(department_id__in=(2,3))


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий
Нет обсуждений. Начните первое.