Запросы ORM
ORM (Object Relational Mapping) является одной из наиболее важных функций, предоставляемых веб-фреймворком Django. ORM используется для взаимодействия с различными реляционными базами данных, такими как SQLite, PostgreSQL и MySQL, через наборы запросов.
Чтобы узнать больше об ORM, нажмите здесь
Операции CRUD
Создать объект
Извлечение объекта
Обновить объект
Удалить объект
Примерная модель
1 | from django.db import models |
1. Создайте объект
Существует три способа создать новый объект в базе данных.
create() method
save() method
get_or_create()
метод create()
1 | Post.objects.create(title=“i love Django”) |
метод save()
Чтобы создать объект, создайте его экземпляр, используя аргументы ключевого слова для класса модели, затем вызовите _save()_
, чтобы сохранить его в базе данных.
1 | post = Post(title="i love Django”) |
Django не попадает в базу данных, пока вы явно не вызовете _save()_
.
Метод _save()_
не имеет возвращаемого значения.
Сохранение ForeignKey
1 | author_1 = Author.objects.get(id=1) |
Сохранение ManyToManyField
1 | _viewers = Viewer.objects.get(id=1) |
get_or_create()
метод get_or_create()
сначала ищет объект с заданными параметрами kwargs и создает его, если не найден.
Возвращает кортеж (object, created), где object - это извлеченный или созданный объект, а created - логическое значение, указывающее, был ли создан новый объект.
Синтаксис
1 | get_or_create(defaults=None, **kwargs) |
Пример
1 | obj, created = Post.objects.get_or_create(title="i love Django") |
default
используется, когда вы не хотите сравнивать значение, чтобы получить объект
1 | obj, created = Author.objects.get_or_create(name=“Jone”, middle_name="Ram", defaults={‘last_name': “Bob”}) |
В приведенном выше примере он будет искать Author с name “Jone” и middle_name “Ram”, а не искать last_name.
Если он найдет его, он вернет этот объект, иначе создаст нового Author с name “Jone”, middle_name “Ram” и last_name “Bob”
2. Извлечение объекта
Чтобы получить данные из базы данных, вам необходимо создать Queryset запросов через Manger в классе model.
Методы набора запросов (QuerySet Methods)
Наиболее часто используемыми методами набора запросов являются:
- all()
- get()
- filter()
- exclude()
all()
метод all()
возвращает набор запросов всех объектов в базе данных.
1 | # get all the post |
Ограничение наборов запросов
Используйте подмножество синтаксиса нарезки массивов Python, чтобы ограничить ваш QuerySet запросов определенным количеством результатов. Это эквивалент предложений SQL LIMIT и OFFSET .
1 | # return first 3 objects (LIMIT 3) |
get()
метод get()
возвращает только один объект, соответствующий заданному запросу.
1 | # retrieve a single post where id is 21 |
Если нет сообщения с идентификатором 21, то метод get()
вызовет исключение DoesNotExist.
1 | try: |
Если более одного элемента соответствует запросу, то это вызовет исключение MultipleObjectsReturned
.
1 | try: |
get_object_or_404( )
метод get_object_or_404()
сначала ищет объект с заданными kwargs, и если он не найден, то выдает ошибку Http404
.
1 | from django.shortcuts import get_object_or_404 |
filter ( )
метод filter()
возвращает объекты набора запросов, которые соответствуют заданному запросу.
1 | # search posts where title contains Django |
exclude( )
возвращать объекты QuerySet, которые не соответствуют заданным параметрам
1 | # exclude post where publish date is greater than 3-1-2021 |
Другие важные методы набора запросов
first ( )
метод first()
вернет один первый объект набора данных.
1 | # retrieve fist post, return single object |
last( )
метод last()
вернет один последний объект набора данных.
1 | # retrieve last post, return single object |
exists ( )
метод exists()
вернет True, если набор запросов содержит какой-либо результат, и False, если нет.
1 | Post.objects.filter(title__isnull=True).exists() |
latest( )
Возвращает последний объект в таблице на основе заданных полей.
1 | Post.objects.latest(‘pub_date’) |
values ( )
метод values()
используется, когда вы хотите выбрать несколько столбцов из таблицы.
метод values()
возвращает набор запросов в виде dictionaries, а не экземпляра модели.
1 | Post.objects.filter(title__isnull=True).values(‘id’, ‘title’) |
values_list( )
метод values_list()
также используется для выбора нескольких столбцов из таблицы. Но values_list()
возвращает QuerySet запросов в виде tuples.
1 | Post.objects.filter(title__isnull=True).values_list(‘id’, ‘title’) |
Если вы установите flat=True
, то он будет возвращать результаты с одиночными значениями, а не с одним кортежем.
1 | Post.objects.filter(title__isnull=True).values_list(‘id’, flat=True) |
flat=True
может использоваться только в том случае, если вы передаете одно поле. Если вы передадите более одного файла, Django выдаст сообщение об ошибке.
Если вы установите named=True
то результатом будет namedtuple()
1 | Post.objects.filter(title__isnull=True).values_list(‘id’, ‘title’, named=True) |
Чтобы получить values_list()
одного экземпляра
1 | Post.objects.values_list(‘id’, ‘title’).get(id=1) |
distinct( )
метод distinct()
устраняет дублирующиеся данные из набора запросов.
1 | Post.objects.distinct() |
reverse( )
метод reverse()
для изменения порядка, в котором возвращаются элементы набора запросов.
1 | my_queryset.reverse() |
order_by( )
Наборы запросов также позволяют упорядочивать список объектов с помощью метода order_by()
.
1 | Post.objects.order_by(‘title’) |
select_related( )
метод select_related()
- это усилитель производительности, который возвращает набор запросов, которые соответствуют связям внешнего ключа, выбирая дополнительные данные связанных объектов при выполнении своего запроса.
1 | # without select_related |
select_related()
ограничен однозначными отношениями — внешним ключом и один-к-одному и не может использоваться для отношений «многие-ко-многим».
prefetch_related( )
Возвращает QuerySet, который автоматически извлекает в одном пакете связанные объекты для каждого из указанных поисковых запросов.
1 | # viewers is in many-to-many relationship with post |
функция prefetch_related()
может использоваться для отношений внешнего ключа, “один к одному” и “многие ко многим”.
Разница между select_related( ) и prefetch_related( )
select_related()
и prefetch_related()
повышают производительность и предназначены для предотвращения потока запросов к базе данных, вызванных доступом к связанным объектам, но стратегия совершенно другая.
select_related()
работает, создавая SQL INNER JOIN и включая поля связанного объекта в оператор SELECT.
prefetch_related()
, с другой стороны, выполняет отдельный поиск для каждой связи и выполняет “joining” в Python.
select_related( )
1 | Post.objects.select_related(‘author’).all() |
prefetch_related()
1 | Post.objects.prefetch_related(‘viewers’).all() |
aggregate ( )
Возвращает словарь совокупных значений (средние значения, суммы и т. д.), рассчитанных по QuerySet.
Каждый аргумент aggregate()
указывает значение, которое будет включено в возвращаемый словарь.
1 | # Return Count of all the viewers on all the posts |
Чтобы узнать больше, нажмите здесь
Aggregatev функции
Django включает в себя семь агрегатных функций:
Avg
Возвращает среднее значение выражения.Count
. Подсчитывает количество возвращенных объектов.Max
. Возвращает максимальное значение выражения.Min
. Возвращает минимальное значение выражения.StdDev
. Возвращает стандартное отклонение совокупности данных в выражении.Sum
. Возвращает сумму всех значений в выражении.Variance
. Возвращает дисперсию совокупности данных в выражении.
annotate( )
Аннотирует каждый объект в QuerySet предоставленным списком выражений запроса.
1 | # Return Count of all the viewers on Post |
метод annotate()
подсчитывает количество viewers для каждого Post и аннотирует количество для каждого объекта QuerySet. Где Aggregate подсчет просмотров для всех сообщений в наборе запросов.
extra ( )
метод extra()
используется для переименования столбцов в ORM.
1 | Post.objects.extra(select={'post_title': 'title'}).values('id', ‘post_title')[0] |
Иногда синтаксис запроса Django сам по себе не может легко выразить сложное предложение WHERE. Для этих крайних случаев Django предоставляет модификатор extra()
QuerySet — хук для внедрения определенных предложений в SQL, сгенерированный QuerySet.
1 | Post.objects.extra(select={'post_author_name': 'Select name FROM myapp_author where myapp_author.id = myapp_post.author_id'}).values('title', 'post_author_name')[0] |
Чтобы узнать больше, нажмите здесь
Сложные запросы с Q объектами
Объекты Q
используются для операций AND , OR и NOT.
Вы можете импортировать объект Q
из django.db.models
1 | from django.db.models import Q |
OR
|
используется для операции OR между 2 Q
выражениями.
1 | # return post where title contains Django or python |
AND
&
используется для операции AND между 2 Q
выражениями.
1 | # return post where title contains Django and python |
NOT
~
используется для NOT операции между 2 Q
выражениями.
1 | # return post where title contains Django and not python |
Выражения запросов
Выражения запроса описывают вычисление или значение, используемое как часть другого запроса. Встроенные выражения запросов:
F()
. Представляет значение поля модели или аннотированного столбца.Func()
. Базовый тип для функций базы данных, таких как LOWER и SUM.Aggregate()
. Все агрегатные функции наследуются от Aggregate().Value()
. Значение выражения. Не используется напрямую.ExpressionWrapper()
. Используется для переноса выражений разных типов.SubQuery()
. Добавьте подзапрос к набору запросов.
Выражения F()
Выражения F()
используются для ссылки на значения полей модели непосредственно в базе данных.
1 | User.objects.annotate(_age=F(‘age’)*2).values(‘id’,’first_name’,’_age’) |
3. Обновить объект
Обновить один объект
1 | post = Post.objects.get(id=1) |
Обновить объект ForeignKey
1 | post = Post.objects.get(id=1) |
Обновить объект ManyToManyKey
1 | post = Post.objects.get(id=1) |
Обновить несколько объектов
1 | Post.objects.filter(author__id__in=[1,2]).update(title="new title”) |
update_or_create( )
метод update_or_create()
, используемый для обновления объекта с помощью заданных kwargs, создавая новый, если это необходимо.
Возвращает кортеж (object, created), где object - это созданный или обновленный объект, а created - логическое значение, указывающее, был ли создан новый объект.
Метод update_or_create
пытается извлечь объект из базы данных на основе заданных kwargs. Если совпадение найдено, оно обновляет поля, переданные в словаре по defaults.
1 | obj, created = Author.objects.update_or_create(name=‘Jone’, defaults={'last_name': 'Bob'}) |
В приведенном выше примере он будет искать Author с именем “Jone”, и если он будет найден, он обновит last_name до “Bob”. И созданная переменная будет иметь значение False. Если есть два или более автора с именем “Jone”. Это вызовет ошибку.
Если Author с именем “Jone” не найден, то будет создан новый Author с именем “Jone” и фамилией “Bob”. И созданная переменная будет иметь значение True.
4. Удалить объект
Удалить один объект
1 | post = Post.objects.get(id=1) |
Удаление нескольких объектов
1 | Post.objects.filter(author__id__in=[1,2]).delete() |