Django Модель Часть 2
В этой части учебника мы продолжим разбирать Django модель, как с ней работать, в прошлой части мы уже рассмотрели как создавать модель, в этой уже научимся с ней полноценно работать, а точнее разберём пару методов.
Для тех кто не читал предыдущую часть, или просто не умеет создавать модель, то тогда посмотрите эту часть по ссылке.
Как работает Django Модель:
Для начала посмотрим как взять элементы, всего их можно взять несколькими способами, вот вам наглядные примеры:
Как видите здесь мы импортировали модель Post , потом мы создали для примера представление get_posts , в которой передаём идентификатор, который потом используем для получения одного поста.
Теперь разберём как получать данные, сначала мы берём из базы данных только один пост, с помощью метода get() , берём мы его по идентификатору, таким образом мы получим первый попавшейся пост с id который мы передали, но вы можете и по другим данным искать посты, если вам надо.
Также вы скорее все заметили, что при получение мы не просто строем конструкцию Post.get() , а делаем Post.objects.get() , всё дело в том, что objects , это специальный дочерний объект нашей модели для работы с элементами этой модели, если вы сделаете иначе, то просто будет ошибка, таким образом сделана работа с моделью в Django.
Следующие мы просто берём все посты, для этого используем Post.objects.all() , вот принципе добавить нечего, этот метод просто берёт все элементы модели.
Последние, это самое интересное, тут мы берём данные по определённому фильтру, для этого используем метод Post.objects.filter() , в нашем случае по категории, тут принцип такой же как и с get() , только теперь берём не первый попавшейся элемент, а все совпадения которые нашли. Ещё вы можете заметить, что мы дополнительно используем метод order_by() , он нужен для сортировки полученных элементов, в нашем случае по id , а минус означает что сортирует по убыванию.
когда разобрались с получением элементов из базы данных, давайте покажу как сохранять их, вот пример кода сохранения:
Python django изменение данных
Рассмотрим пример с редактированием и удалением объектов модели на примере модели Person:
from django.db import models class Person(models.Model): name = models.CharField(max_length=20) age = models.IntegerField()
Обновление
save()
Для обновления объекта также применяется метод save() :
bob = Person.objects.get(id=2) bob.name = "Bob" bob.save()
В этом случае Django полностью обновляет объект, все его свойства, даже если мы их не изменяли. Чтобы указать, что нам надо обновить только определенные поля, следует использовать параметр update_fields :
from .models import Person bob = Person.objects.get(id=1) bob.name = "Robert" bob.save(update_fields=["name"])
Это позволит повысить производительность.
update()
Другой способ обновления объектов представляет метод update() (и его асинхронная версия aupdate() ) в сочетании с методом filter , которые вместе выполняют один запрос к базе данных:
from .models import Person number = Person.objects.filter(id=1).update(name="Mike") print(result) # количество обновленных строк
В данном случае у объектов с устанавливаем для поля name значение «Mike». Метод возвращает количество обновленных строк.
Если нам не надо получать обновляемый объект, то данный способ позволит нам увеличить производительность взаимодействия с бд.
Также можно установить и большое количество полей:
Person.objects.filter(id=1).update(name="Mike", age = 33)
Иногда бывает необходимо изменить значение столбца в бд на основании уже имеющегося значения. В этом случае мы можем использовать функцию F() :
from .models import Person from django.db.models import F Person.objects.all(id=2).update(age = F("age") + 1)
В данном случае полю age присваивается уже имеющееся значение, увеличенное на единицу.
При этом важно учитывать, что метод update обновляет все записи в таблице, которые соответствуют условию.
Если надо обновить вообще все записи, вне зависимости от условия, то необходимо комбинировать метод update с методом all() :
from .models import Person from django.db.models import F Person.objects.all().update(name="Mike") Person.objects.all().update(age = F("age") + 1)
update_or_create()
Метод update_or_create (и его асинхронная версия aupdate_or_create() ) обновляет запись, а если ее нет, то добавляет ее в таблицу:
values_for_update= bob, created = Person.objects.update_or_create(id=2, defaults = values_for_update)
Метод update_or_create() принимает два параметра. Первый параметр представляет критерий выборки объектов, которые будут обновляться. Второй параметр представляет объект со значениями, которые получат выбранные объекты. Если критерию не соответствует никаких объектов, то в таблицу добавляется новый объект, а переменная created будет равна True.
bulk_update()
Метод bulk_update() (и его асинхронная версия abulk_update() ) позволяет обновить за один раз набор объектов.
bulk_update(objs, fields, batch_size=None)
Первый параметр — obj указывает на обновляемые объекты, а второй параметр — fields представляет обновляемые поля с новыми значениями. Последний параметр — batch_size указывает, сколько объектов обновляется в одном запросе (по умолчанию обновляются все объекты)
from .models import Person first_person = Person.objects.get(id=1) first_person.name = "Tomas" second_person = Person.objects.get(id=2) second_person.age = 29 number = Person.objects.bulk_update([first_person, second_person], ["name", "age"]) print(number) # 2
В данном случае у первого объекта обновляется значение поля «name», а у второго — значение поля «age». Поэтому в качестве второго параметра передается список с данными полями. Результатом метода является количество обновленных объектов.
Данный метод имеет некоторые ограничения. В частности, мы не можем обновить значение первичного ключа. Также если в обновляемом наборе есть дубли, то только первое вхождение объекта будет использоваться для обновления.
Удаление
Для удаления мы можем вызвать метод delete() (либо его асинхронную версию adelete() ) у удаляемого объекта:
person = Person.objects.get(id=2) person.delete()
Если не требуется получение отдельного объекта из базы данных, тогда можно удалить объект с помощью комбинации методов filter() и delete() :
Person.objects.filter(id=4).delete()
Удаление всех данных из таблицы:
Python django изменение данных
Рассмотрим базовые операции с моделями на простейшем примере. создание и вывод объектов модели на примере. Пусть, в файле models.py определена модель Person:
from django.db import models class Person(models.Model): name = models.CharField(max_length=20) age = models.IntegerField()
Определение представлений
В файле views.py пропишем четыре представления для получения, сохранения, редактирования и удаления данных:
from django.shortcuts import render from django.http import HttpResponseRedirect, HttpResponseNotFound from .models import Person # получение данных из бд def index(request): people = Person.objects.all() return render(request, "index.html", ) # сохранение данных в бд def create(request): if request.method == "POST": person = Person() person.name = request.POST.get("name") person.age = request.POST.get("age") person.save() return HttpResponseRedirect("/") # изменение данных в бд def edit(request, id): try: person = Person.objects.get(id=id) if request.method == "POST": person.name = request.POST.get("name") person.age = request.POST.get("age") person.save() return HttpResponseRedirect("/") else: return render(request, "edit.html", ) except Person.DoesNotExist: return HttpResponseNotFound("Person not found
") # удаление данных из бд def delete(request, id): try: person = Person.objects.get(id=id) person.delete() return HttpResponseRedirect("/") except Person.DoesNotExist: return HttpResponseNotFound("Person not found
")
В функции index() получаем все данные с помощью метода Person.objects.all() и передаем их в шаблон index.html.
В функции create() получаем данные из запроса типа POST, сохраняем данные с помощью метода save() и выполняем переадресацию на корень веб-сайта (то есть на функцию index).
Функция edit выполняет редактирование объекта. Функция в качестве параметра принимает идентификатор объекта в базе данных. И вначале по этому идентификатору мы пытаемся найти объект с помощью метода Person.objects.get(id=id) . Поскольку в случае отсутствия объекта мы можем столкнуться с исключением Person.DoesNotExist, то соответственно нам надо обработать подобное исключение, если вдруг будет передан несуществующий идентификатор. И если объект не будет найден, то пользователю возващается ошибка 404 через вызов return HttpResponseNotFound() .
Если объект найден, то обработка делится на две ветви. Если запрос POST, то есть если пользователь отправил новые изменненые данные для объекта, то сохраняем эти данные в бд и выполняем переадресацию на корень веб-сайта. Если запрос GET, то отображаем пользователю страницу edit.html с формой для редактирования объекта.
Функция delete аналогичным образом находит объет и выполняет его удаление.
Определение шаблонов
В папке templates определим шаблон index.html , который будет выводить данные на веб-страницу:
0 %>
Список пользователей
Id Имя Возраст > > > >">Изменить | >">Удалить
В начале шаблона определена форма для добавления данных, которые потом будет получать функция create в POST-запросе. А ниже определена таблица, в которую выводятся данные из переданного из представления набора people. В каждой строке определены ссылки на редактирование и удаление объекта.
Теперь добавим в папку templates файл edit.html со следующим содержимым:
>" />
>" />
Здесь определена форма для редактирования объекта. По нажатию на кнопку введенные на форму данные будут уходить по тому же адресу в запросе POST.
Установка маршрутов
И также в файле urls.py проекта свяжем маршруты с представлениями:
from django.urls import path from hello import views urlpatterns = [ path("", views.index), path("create/", views.create), path("edit//", views.edit), path("delete//", views.delete), ]
В итоге получится следующая структура проекта:
Запустим проект и обратимся к приложению в браузере. Вначале добавим несколько объектов через форму на веб-странице. И после каждого добавления мы увидим, как на веб-странице в таблице появляются новые данные:
Нажав на ссылку редактирования, мы перейдем к форме, где мы сможем изменить значения выбранного объекта:
Соответственно нажав на кнопку удаления в таблице объектов, мы удалим выбранный объект.