В центре работы с моделями и базы данными находится объект QuerySet и его методы. QuerySet представляет набор запросов к базе данных, а его методы создают подобные запросы. А Django позволяет транслировать вызовы методов QuerySet в соответствующие SQL-запросы. Отмечу основые методы, которые можно применять для работы с данными моделей:
filter(): фильтрует набор данных и возвращает выборку данных, которая соответствует фильтру, также в виде объекта QuerySet
exclude(): фильтрует набор данных и возвращает выборку, которая НЕ соответствует фильтру, в виде объекта QuerySet
order_by(): сортирует набор данных и возвращает отсортированную выборку в виде объекта QuerySet
distinct(): возвращает объект QuerySet, который содержит только уникальные объекты
values(): возвращает данные объектов в виде словаря
values_list(): возвращает данные объектов в виде списка
none(): возвращает пустой набор данных в виде объекта EmptyQuerySet (класс производный от QuerySet)
all(): возвращает объект QuerySet, который содержит все объекты из таблицы
union(): объединяет два объекта QuerySet и возвращает объединенный объект QuerySet
intersection(): возвращает пересечение двух объектов QuerySet в виде другого QuerySet
difference(): возвращает разность двух объектов QuerySet в виде другого QuerySet
raw(): выполняет переданный в качестве параметра SQL-запрос
get(): возвращает один объект модели
create(): создает один объект модели
get_or_create(): возвращает один объект модели по указанным параметрам, а если он отсутствует, то создает его
update_or_create(): обновляет один объект модели по указанным параметрам, а если он отсутствует, то создает его
bulk_create(): создает набор объектов модели
save(): сохраняет один объект модели (если он ранее остутствовал в БД, то добавляет его, есть присутствовал, то обновляет его)
bulk_update(): обновляет набор объектов
count(): возвращает количество объектов в наборе
in_bulk(): возвращает словарь объектов, которые имеют определенные идентификаторы
latest(): возвращает объект с самыми последними изменениями
earliest(): возвращает объект с самыми ранними изменениями
first(): возвращает первый объект набора
last(): возвращает последний объект набора
aggregate(): выполняет агрегатную функцию (нахождение суммы, среднего, минимального, максимального значения и т.д.) и возвращает результат в виде числа
exists(): проверяет, есть ли в наборе как минимум один объект. Если есть, то возвращается True, иначе возвращается False
contains(): проверяет, есть ли в наборе определенный объект. Если есть, то возвращается True, иначе возвращается False
update(): обновляет один объект модели
delete(): удаляет один объект модели
Полный список методов можно найти в документации.
Причем выполнение методов QuerySet в базе данных происходит не сразу - при вызове метода, а при получение конкретного результата их QuerySet, например, при переборе набора. Посмотрим выполнение методов на примере. Допустим, в файле models.py определена следующая модель Person:
from django.db import models class Person(models.Model): name = models.CharField(max_length=20) age = models.IntegerField()
Для упрощения протестируем код в файле views.py, код которого вызывается при запуске приложения. В частности, определим в нем следующий код:
from .models import Person # получаем все объекты people = Person.objects.all() print(people.query) # получаем объекты с именем Tom people = people.filter(name = "Tom") print(people.query) # получаем объекты с возрастом, равным 31 people = people.filter(age = 31) print(people.query) # здесь происходит выполнения запроса в БД for person in people: print(f"{person.id}.{person.name} - {person.age}")
Сначала идет получение всех данных с помощью метода all()
:
people = Person.objects.all()
Переменная people
здесь будет представлять объект QuerySet, который представляет набор из всех объектов таблицы.
С помощью свойства query у результата запроса мы можем получить SQL-запрос и, например, вывести его на консоль:
print(people.query)
Затем фильтруем набор с помощью метода filter()
и выбираем только те объекты, где поле name равно "Tom":
people = people.filter(name = "Tom")
Метод filter также возвращает QuerySet, который присваивается той же переменной people.
Затем выбираем только те объекты, где поле name равно "Tom":
people = people.filter(age = 31)
Таким образом, к набору QuerySet были применены три метода, однако ни в одном случае не происходит обращения к базе данных. Это происходит, только когда мы непосредственно обращаемся к объектам набора, перебирая их в цикле.
for person in people: print(f"{person.id}.{person.name} - {person.age}")
А по консольному выводу мы можем увидеть, как у нас создается финальный SQL-запрос, который и будет выполняться в БД при переборе объектов в цикле: