Рассмотрим добавление в базу данных и получение из нее на примере модели Person:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
age = models.IntegerField()
Для добавления данных применяется метод create():
tom = Person.objects.create(name="Tom", age=23)
Если добавление пройдет успешно, то объект будет иметь id, который можно получить через tom.id.
Асинхронная версия метода - acreate
from .models import Person
import asyncio
async def acreate_person():
person = await Person.objects.acreate(name="Tim", age=26)
print(person.name)
# запускаем асинхронную функцию acreate_person
asyncio.run(acreate_person())
Однако в своей сути метод create() использует другой метод - save(), который мы также можем использовать отдельно
для добавления объекта:
tom = Person(name="Tom", age=23) tom.save()
После успешного добавления также можно получить идентификатор добавленной записи с помощью tom.id.
Метод bulk_create() (и его асинхронная версия abulk_create()) позволяет добавить набор объектов, который передается в в метод в качестве параметра:
from .models import Person
people = Person.objects.bulk_create([
Person(name="Kate", age=24),
Person(name="Ann", age=21),
])
for person in people:
print(f"{person.id}. {person.name}")
Метод get() возвращает один объект по определенному условию, которое передается в качестве параметра:
tom = Person.objects.get(name="Tom") # получаем запись, где name="Tom" bob = Person.objects.get(age=23) # получаем запись, где age=42
При использовании этого метода надо учитывать, что он предназначен для выборки таких объектов, которые имеются в единичном числе в базе данных. Если
в таблице не окажется подобного объекта, то мы получим ошибку имя_модели.DoesNotExist. Если же в таблице будет несколько объектов, которые соответствуют
условию, то будет сгенерированно исключение MultipleObjectsReturned. Поэтому следует применять данный метод с осторожностью, либо применять
обработку соответствующих исключений:
from .models import Person
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
try:
tom = Person.objects.get(name="Tom") # MultipleObjectsReturned
alex = Person.objects.get(name="Alex") # ObjectDoesNotExist
except ObjectDoesNotExist:
print("Объект не сушествует")
except MultipleObjectsReturned:
print("Найдено более одного объекта")
Асинхронная версия метода называется aget:
from .models import Person
import asyncio
async def get_person():
person = await Person.objects.aget(id=1)
print(person.name)
# запускаем асинхронную функцию get_person
asyncio.run(get_person())
Метод get_or_create() (и его асинхронная версия aget_or_create) возвращает объект, а если его нет в бд, то добавляет в бд новый объект.
bob, created = Person.objects.get_or_create(name="Bob", age=24) print(created) print(bob.name) print(bob.age)
В данном случае, если в таблице нет объекта со значениями name="Bob" и age=24, то он добавляется. Если есть, то он возвращается.
Метод возвращает добавленный объект (в данном случае переменная bob) и булевое значение (created), которое хранит True, если добавление прошло успешно.
Стоит учитывать, что если в таблице уже есть несколько объектов (два и больше) с указанными значениями, то сгенерируется исключение MultipleObjectsReturned.
Если необходимо получить все имеющиеся объекты, то применяется метод all():
people = Person.objects.all()
Данный метод возвращает объект типа QuerySet.
Если надо получить все объекты, которые соответствуют определенному критерию, то применяется метод filter(), который в качестве параметра принимает критерий выборки:
people = Person.objects.filter(age=23) # использование нескольких критериев people2 = Person.objects.filter(name="Tom", age=23)
Метод filter позволяет определять более сложные условия, но поскольку это отдельная большая тем, то подробнее будет рассмотрена в отдельной статье.
Метод exclude() позволяют исключить из выборки записи, которые соответвуют переданному в качестве параметра критерию:
# исключаем пользователей, у которых age=23 people = Person.objects.exclude(age=23)
Можно комбинировать два выше рассмотренных метода:
# выбираем всех пользователей, у которых name="Tom" кроме тех, у которых age=23 people = Person.objects.filter(name="Tom").exclude(age=23)
Метод in_bulk() (и его асинхронная версия ain_bulk) является более эффективным способом для чтения большого количества записей. В качестве параметра в него можно передать список идентификаторов объектов, которые надо получить. В качестве результата он возвращает словарь, то есть объект dict:
# получаем все объекты people = Person.objects.in_bulk() for id in people: print(people[id].name) print(people[id].age) # получаем объекты с id=1 и id=3 people2 = Person.objects.in_bulk([1,3]) for id in people2: print(people2[id].name) print(people2[id].age)
Метод in_bulk() возвращает словарь, где ключи представляют id объектов, а значения по этим ключам - собственно эти объекты, то есть в данном случае объекты Person.
С помощью синтаксиса списков можно получить определенную порцию данных из QuerySet:
from .models import Person people = Person.objects.all()[:5]
В данном случае выбираем первые 5 объектов, что на уровне базы данных транслируется в SQL-выражение LIMIT 5
Первый параметр указывает, сколько объектов надо пропустить:
from .models import Person
people = Person.objects.all()[5:10]
for person in people:
print(f"{person.id}.{person.name} - {person.age}")
В данном случае пропускаем первые 5 объектов и выбираем следующие 5 объектов до 10-го индекса, что на уровне базы данных транслируется в выражение OFFSET 5 LIMIT 5