Наша цель — научиться обновлять и удалять записи в базе данных. Это крайне важно, поскольку данные редко остаются неизменными: пользователи обновляют профили, добавляют и удаляют посты, закладки и еще массу всего. И всё это вы сможете делать на лету с помощью Django ORM.
Обновление записей: основы
Обновление данных — это повседневная задача для любого приложения. Например, допустим, у нас есть модель Book, и нам нужно обновить название книги или год её публикации. Давайте сначала посмотрим, как это делается.
Вот пример нашей модели, которую мы будем использовать в этой лекции:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
published_year = models.IntegerField()
def __str__(self):
return f"{self.title} by {self.author}"
Обновление объекта
Чтобы обновить запись, мы сначала должны найти её в базе данных. После этого просто изменяем параметры объекта и вызываем метод .save().
from myapp.models import Book
# Найдем книгу, которую хотим обновить
book = Book.objects.get(id=1)
# Изменим её название
book.title = "Новое название книги"
book.published_year = 2023
# Сохраним изменения
book.save()
print(f"Книга обновлена: {book.title}, {book.published_year}")
Когда вы вызываете метод save(), Django автоматически формирует SQL-запрос UPDATE, чтобы изменить соответствующую запись в базе данных.
Обновление множества записей
Иногда нужно обновить сразу несколько записей. Например, нужно установить новый год публикации для всех книг определенного автора. Django ORM предоставляет для этой цели метод update().
# Обновим год публикации для всех книг автора "Толстой"
Book.objects.filter(author="Толстой").update(published_year=2022)
print("Все книги автора 'Толстой' обновлены!")
Метод update() выполняет один SQL-запрос, поэтому это гораздо быстрее, чем обновление каждой записи через save() в цикле. Более того, метод update() не вызывает сигнал save(), что тоже нужно учитывать в сложных проектах.
Особенности обновления данных
При обновлении данных стоит учитывать несколько важных моментов:
- Проверка существования записи: если вы используете метод
.get(), а запись не найдена, Django выбросит исключениеDoesNotExist. Поэтому не забывайте использоватьtry-exceptили проверять существование записи с помощью метода.exists().
try:
book = Book.objects.get(id=99) # Пытаемся найти запись
book.title = "Ошибка 404"
book.save()
except Book.DoesNotExist:
print("Книга с таким ID не найдена!")
Ленивая загрузка QuerySet: Django ORM экономит ресурсы за счет ленивой загрузки данных. Пока вы не пытаетесь использовать объекты из QuerySet, SQL-запрос не выполняется. Это нужно учитывать при выполнении массовых операций.
Перезапись данных: при вызове
save()Django обновляет все поля модели. Если вы используете методupdate(), он модифицирует только указанные вами поля.
Удаление записей
Теперь перейдем к следующей задаче — удалению записей. Например, пользователь может удалить пост в блоге, и эта запись должна быть удалена из базы данных.
Удаление одного объекта
Чтобы удалить одну запись, используется метод .delete().
# Найдем книгу и удалим её
book = Book.objects.get(id=1)
book.delete()
print("Книга удалена!")
Здесь Django формирует SQL-запрос DELETE и удаляет запись из базы данных. Важно отметить, что метод .delete() вызывает сигналы pre_delete и post_delete, что может быть полезно для выполнения дополнительных действий.
Удаление нескольких записей
Если нужно удалить несколько записей, можно использовать метод filter() вместе с delete().
# Удалим все книги автора "Безымянный автор"
Book.objects.filter(author="Безымянный автор").delete()
print("Все книги 'Безымянного автора' удалены!")
Подобно методу update(), метод delete() для QuerySet выполняет один SQL-запрос, что делает его намного быстрее, чем удаление записей через цикл.
Удаление всех записей
Есть ли у вас желание "немного похулиганить"? Тогда вот так можно удалить все записи из таблицы:
# Удаляем абсолютно все книги
Book.objects.all().delete()
print("Собрание библиотеки удалено. Надеюсь, это не было случайностью.")
Но будьте осторожны с этим кодом! Это действие необратимо. Если вы случайно удалите все записи, восстановить их можно будет только из бэкапа, если он у вас есть.
Предостережения и типичные ошибки
Как и в случае с обновлением данных, работа с удалением записей требует особой осторожности:
Проверка существования записей: перед удалением убедитесь, что записи действительно существуют, иначе вызов
delete()может ничего не сделать (что, конечно, не вызовет ошибку, но может сбить с толку).Каскадное удаление: если у вас в модели есть внешние ключи (
ForeignKey), удаление записи может привести к каскадному удалению связанных объектов. Это поведение можно настроить с помощью атрибутаon_deleteв полеForeignKey.
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
# Удаление автора приведет к удалению всех его книг
- Журналы действий: в продакшене вместо прямого удаления часто используется концепция "мягкого удаления" (soft delete). Это значит, что запись остается в базе данных, но помечается как удаленная. Это удобно для аудита и восстановления данных.
class Book(models.Model):
title = models.CharField(max_length=200)
is_deleted = models.BooleanField(default=False)
def delete(self):
self.is_deleted = True
self.save()
Практическое задание
Задание 1: Обновление записей
- Добавьте в вашу модель
Bookновое полеgenre(жанр книги) с типомCharField. - С помощью Django shell обновите жанр для всех книг автора "Пушкин" на "Классика".
- Проверьте обновления, получив все книги этого автора.
Задание 2: Удаление записей
- Удалите все книги, у которых год публикации меньше 2000.
- Реализуйте "мягкое удаление" для модели
Book. Для этого добавьте полеis_deletedи измените логику методаdelete().
Теперь вы умеете обновлять и удалять записи в базе данных с помощью Django ORM. Эти навыки пригодятся вам не только в учебных проектах, но и в реальных приложениях, где данные постоянно меняются. С таким инструментарием вы уже готовы к следующим этапам работы с Django.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ