Методы выбора записей. Методы exists() и count()

Курс по Django: https://stepik.org/a/183363

Продолжаем знакомиться с ORM Django и начнем это занятие с некоторых дополнительных и полезных методов извлечения записей. Например, чтобы взять первую запись из выборки, используется метод first():

Women.objects.first()

То есть, берется первая запись в соответствии с порядком сортировки модели. Мы можем поменять этот порядок и с помощью этого же метода first() выбирать разные записи, например, так:

Women.objects.order_by("pk").first()
Women.objects.order_by("-pk").first()

Или же воспользоваться аналогичным методом last() для выбора последней записи из набора:

Women.objects.order_by("pk").last()
Women.objects.filter(pk__gt=5).last()

Методы latest и earliest

Если в таблице присутствуют поля с указанием даты и времени, то для таких записей и таких таблиц можно применять методы:

  • latest() – выбор записи с самой поздней датой (наибольшей);
  • earliest() – выбор записи с самой ранней датой (наименьшей).

Например:

Women.objects.earliest("time_update")
Women.objects.latest("time_update")

Для чего могут понадобиться такие методы? Например, сделана выборка с сортировкой по какому-либо другому полю (не time_update) и из этой выборки нужно получить самую раннюю или самую позднюю запись:

Women.objects.order_by('title').earliest("time_update")

получаем запись с самой ранней датой изменения.

Методы get_previous_by_, get_next_by_

Далее, если нужно выбрать предыдущую или следующую запись относительно текущей, то в ORM для этого существует два специальных метода, которые выбирают записи опять же по указанному полю с датой и временем. Например, мы выбираем некую запись с pk=2:

w = Women.objects.get(pk=2)

Тогда, для получения предыдущей записи относительно текущей, можно записать:

w.get_previous_by_time_update()

Здесь суффикс time_update – это название поля, по которому определяется предыдущая запись. То есть, здесь используется не порядок следования записей в выборке, а временное поле. И уже по нему смотрится предыдущая или следующая запись:

w.get_next_by_time_update()

Дополнительно в этих методах можно указывать условия выборки следующей или предыдущей записи. Например:

w.get_previous_by_time_update(pk__gt=6)

выбирается предыдущая запись с id больше 6.

Методы exists и count

В ORM Django имеются два весьма полезных метода с высокой скоростью исполнения:

  • exists() – проверка существования записи;
  • count() – получение числа записей.

Они часто используются для реализации простых проверок до выполнения других, более сложных запросов.

Давайте я добавлю в таблицу Category еще одну рубрику «Спортсменки»:

Category.objects.create(name="Спортсменки", slug="sportsmenki")

Эта рубрика пока у нас пуста, то есть, нет ни одной записи с ней связанной. Как вы уже догадались, мы сейчас протестируем метод exists(), который возвращает True, если записи есть и False – в противном случае.

c3 = Category.objects.get(pk=3)
c3.posts.exists()

Обратите внимание, мы обращаемся к атрибуту posts, который формируется благодаря наличию параметра related_name='posts' в классе ForeignKey модели Women. Если бы этого параметра не было, то нам следовало бы обращаться к связанным постам так:

c3.women_set.exists()

Итак, мы видим значение False при выполнении запроса, который означает отсутствие каких-либо связанных записей. А, например, для второй категории:

c2 = Category.objects.get(pk=2)
c2.posts.exists()

получим значение True. Соответственно, вызывая второй метод, можем получить число записей:

c2.posts.count()

или эту же операцию можно сделать так:

Women.objects.filter(cat=c2).count()

То есть, методы exists() и count() можно применить к любой выборке.

Курс по Django: https://stepik.org/a/183363

Видео по теме