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

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

5.4 Работа с наборами запросов QuerySet и менеджерами
3 из 15 шагов пройдено
0 из 56 баллов  получено

Извлечение объектов

Одиночный объект извлекается из базы данных методом get(). Мы применили этот метод посредством метода Post.objects.get().

Каждая модель Django имеет по меньшей мере один модельный менеджер, а менеджер, который применяется по умолчанию, называется objects. Набор запросов QuerySet можно получать с помощью модельного менеджера.

Для того чтобы извлечь все объекты из таблицы, используется метод all() применяемого по умолчанию менеджера objects. Например:

all_posts = Post.objects.all()

Вот как мы создаем набор запросов QuerySet, который возвращает все объекты базы данных.

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

Если не назначать набор запросов QuerySet переменной, а вместо этого писать его непосредственно в оболочке Python, то инструкция SQL набора запросов будет исполняться, потому что вы побуждаете ее генерировать результат:

 

Применение метода filter()

Для фильтрации набора запросов QuerySet можно использовать метод filter() менеджера.

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

Post.objects.filter(publish__year=2023)

Фильтрация также может выполняться по нескольким полям.

Например, все посты, опубликованные в 2023 году автором с пользовательским именем admin, можно получить следующим образом:

Post.objects.filter(publish__year=2023, author__username='admin')

Это приравнивается к формированию одного и того же набора запросов QuerySet, соединяющего несколько фильтров в цепочку:

Post.objects.filter(publish__year=2023) \ 

            .filter(author__username='admin')

 

Применение метода exclude()

Определенные результаты можно исключать из набора запросов QuerySet, используя метод exclude() менеджера.

Например, все посты, опубликованные в 2023 году, заголовки которых не начинаются со слова Как, можно получить следующим образом:

Post.objects.filter(publish__year=2023).exclude(title__startswith='Как')

 

Применение метода order_by()

Используя метод order_by() менеджера, можно упорядочивать результаты по разным полям. Например, можно извлечь все объекты, упорядоченные по их полю title, как показано ниже:

Post.objects.order_by('title')

Подразумевается возрастающий порядок. Убывающий порядок указывается с помощью префикса с отрицательным знаком:

Post.objects.order_by('-title')

 

Удаление объектов

Если необходимо удалить объект, то это можно сделать из экземпляра объекта, используя метод delete():

post = Post.objects.get(id=2)
post.delete()

На данном изображении видим, что мы удалили пост с id=2, а именно пост Another post который мы создали запросом в прошлом шаге.

Обратите внимание, что удаление объектов также приводит к удалению любых зависимых взаимосвязей объектов ForeignKey, в случае если параметр on_delete задан равным значению CASCADE.


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

я так понял, двойное подчеркивание в случае author__username='admin' выполняет за кулисами JOIN и объединяет таблицы blog_post и auth_user. Но при этом в случае publish__year никаких JOIN'ов не происходит, не совсем понятна логика, если честно. Как это работает?

@Агаси_Мироян__year это встроенная возможность поиска по полям с датой через WHERE в SQL. Подробнее можете почитать тут - https://docs.djangoproject.com/en/4.2/ref/models/querysets/#field-lookups

@Илья_Перминов, это я знаю, но выходит, что двойное подчеркивание, по сути, универсальное средство, которая позволяет нам свободно получать доступ как к полям из таблицы blog_post, так и к полям таблицы, с которой  blog_post связан по ForeignKey.

@Агаси_Мироян, Да, мы можем использовать двойное подчеркивание как для доступа к полям внешних ключей, так и для для создания конструкций типа exact, gt, gte, lt, date, year и тд.

@Илья_Перминов, Спасибо, теперь стало понятней.

@Шамбер_Егор, спасибо, исправил.