Рассмотрим добавление в базу данных и получение из нее на примере модели 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