Создание и получение объектов модели

Последнее обновление: 26.08.2022

Рассмотрим добавление в базу данных и получение из нее на примере модели Person:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()

Добавление данных

create

Для добавления данных применяется метод 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())

save

Однако в своей сути метод create() использует другой метод - save(), который мы также можем использовать отдельно для добавления объекта:

tom = Person(name="Tom", age=23)
tom.save()

После успешного добавления также можно получить идентификатор добавленной записи с помощью tom.id.

bulk_create()

Метод 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

Метод 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()

Если необходимо получить все имеющиеся объекты, то применяется метод all():

people = Person.objects.all()

Данный метод возвращает объект типа QuerySet.

filter()

Если надо получить все объекты, которые соответствуют определенному критерию, то применяется метод filter(), который в качестве параметра принимает критерий выборки:

people = Person.objects.filter(age=23)
# использование нескольких критериев
people2 = Person.objects.filter(name="Tom", age=23)

Метод filter позволяет определять более сложные условия, но поскольку это отдельная большая тем, то подробнее будет рассмотрена в отдельной статье.

exclude()

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

# исключаем пользователей, у которых age=23
people = Person.objects.exclude(age=23)

Можно комбинировать два выше рассмотренных метода:

# выбираем всех пользователей, у которых name="Tom" кроме тех, у которых age=23
people = Person.objects.filter(name="Tom").exclude(age=23)

in_bulk()

Метод 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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850