Django 5 для начинающих

Прогресс по курсу:  9/1004

3.5 Django ORM, методы возвращающие QuerySet
3 из 9 шагов пройдено
0 из 30 баллов  получено

order_by()

Чтобы переопределить порядок сортировки по умолчанию, вы используете order_by() метод QuerySet. В следующем примере используется метод order_by() для сортировки сотрудников по имени, в порядке возрастания:

Worker.objects.order_by('first_name')

Вы также можете использовать метод order_by() для сортировки сотрудников по имени, в порядке убывания:

Worker.objects.order_by('-first_name')

Также метод order_by() позволяет сортировать результаты по нескольким полям. Например, в следующем примере используется метод order_by() для сортировки сотрудников по имени и фамилии:

Worker.objects.order_by('first_name','last_name')

Чтобы отсортировать случайным образом, вы можете использовать вопросительный знак ?:

Worker.objects.order_by('?')

Метод order_by('?') с параметром случайной сортировки может быть медленным и ресурсозатратным, в зависимости от используемой базы данных.

 

values()и values_list()

В SQL мы можем использовать SELECT операторы, чтобы определить, какие поля возвращаются запросом. В Django мы можем эмулировать это, используя методы .values() или .values_list().

Оба позволят вам контролировать, какие поля выбираются запросом, метод .values вернет QuerySet словарей, а метод .values_list вернет QuerySet кортежей.

>>> Worker.objects.filter(id=1).values()
<QuerySet [{'id': 1, 'first_name': 'Roger', 'last_name': 'Campbell', 'age': 25, 'created': datetime.datetime(2023, 11, 14, 5, 37, 28, 711550, tzinfo=datetime.timezone.utc), 'work_experience': 5}]>

 

>>> Worker.objects.filter(id=1).values_list()
<QuerySet [(1, 'Roger', 'Campbell', 25, datetime.datetime(2023, 11, 14, 5, 37, 28, 711550, tzinfo=datetime.timezone.utc), 5)]>

Также вы можете указать, какие поля хотите вернуть:

>>> Worker.objects.filter(last_name='Medina').values_list('first_name', 'last_name')
<QuerySet [('Ryan', 'Medina')]>

 

dates() и datetimes()

Методы dates() и datetimes() позволяют возвращать из базы данных привязанные к времени записи (например, все события, происходящие в конкретном месяце). Для метода dates() это ограничения времени по году, месяцу, неделе и дню. Для метода datetimes() добавляются ещё и ограничения по часам, минутам и секундам. Например:

>>> Worker.objects.dates('created', 'day')
<QuerySet [datetime.date(2023, 11, 14)]>

 

defer()

Если в вашей модели Django есть поля, содержащие много данных, и вам не нужны эти поля для определенного запроса, вы можете указать Django не извлекать их с помощью метода defer(). Попробуем вывести первого работника и посмотреть его содержание:

>>> w = Worker.objects.get(id=1)
>>> w.__dict__

Мы видим что у него есть поле 'created'. Попробуем извлечь первого работника используя метод defer чтобы не выводить их дату создания:

w = Worker.objects.defer('created').get(id=1)
w.__dict__

То как мы видим, данное поле не было выведено.

 

only()

Является противоположностью метода defer() - возвращает только поля, предоставленные в качестве аргументов:

w = Worker.objects.only('first_name', 'last_name').get(id=1)
w.__dict__

 

 

Это далеко не все методы по Django ORM, но эти методы самые основные. Очень важно понимать как они работают. Основное преимущество методов которые возвращают QuerySet это их ленивость, тоесть мы можем писать стопку этих запросов, но выполнятся они в самом конце.

>>> w = Worker.objects.filter(first_name='Michael').filter(last_name='Smith').exclude(work_experience=5)
>>> print(w.query)
SELECT "orm_method_worker"."id",
       "orm_method_worker"."first_name",
       "orm_method_worker"."last_name",
       "orm_method_worker"."age",
       "orm_method_worker"."created",
       "orm_method_worker"."work_experience"
FROM "orm_method_worker"
WHERE ("orm_method_worker"."first_name" = Michael
       AND "orm_method_worker"."last_name" = Smith
       AND NOT ("orm_method_worker"."work_experience" = 5))

Или так:

>>> a = Worker.objects.filter(first_name='Michael')
>>> b = a.filter(last_name='Smith')
>>> c = b.exclude(work_experience=5)
>>> print(c.query)
SELECT "orm_method_worker"."id",
       "orm_method_worker"."first_name",
       "orm_method_worker"."last_name",
       "orm_method_worker"."age",
       "orm_method_worker"."created",
       "orm_method_worker"."work_experience"
FROM "orm_method_worker"
WHERE ("orm_method_worker"."first_name" = Michael
       AND "orm_method_worker"."last_name" = Smith
       AND NOT ("orm_method_worker"."work_experience" = 5))

Для QuerySet можно объединить несколько фильтров, но они не коснутся базы данных, до тех пор пока QuerySet не будет выполнен. А он исполняется в следующих условиях:

  • При первой итерации по QuerySet.
  • При получении среза, например Worker.objects.all()[:3].
  • При сериализации или кэшировании объектов.
  • При вызове repr() или len().
  • При прямом вызове list().
  • При проверке QuerySet в других выражениях, например bool()orand или if.

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

Ошибка Employee.objects.order_by('-first_name') должно быть не employee а Worker

@User_680720505, спасибо, исправил.

Определить ?

@Дмитрий_Чекмасов, да так лучше будет, спасибо за замечание.

Методы date() и datetimes() позволяют возвращать из базы данных привязанные к времени записи (например, все события, происходящие в конкретном месяце). Для функции date() это ограничения времени по году, месяцу, неделе и дню. datetime()добавляет ограничения по часам, минутам и секундам. Несколько примеров:

Наверно тут dates() и datetimes()

@Evgeny_Bulokhov, спасибо, исправил.