Python django model save
Рассмотрим добавление в базу данных и получение из нее на примере модели 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". ")
Получение из бд
Получение одного объекта
Метод 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() :
Данный метод возвращает объект типа 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) # получаем объекты с и = 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". - ")
В данном случае пропускаем первые 5 объектов и выбираем следующие 5 объектов до 10-го индекса, что на уровне базы данных транслируется в выражение OFFSET 5 LIMIT 5