JavaRush /Курсы /Модуль 3: Django /Обновление данных в базе

Обновление данных в базе

Модуль 3: Django
8 уровень , 4 лекция
Открыта

Давайте займемся обновлением данных. Если создание новых объектов похоже на рождение младенца в базе данных, то обновление — это что-то вроде "смены наряда" или "новой прически" для существующего объекта. Мы изучим два основных способа обновления данных: массовое обновление через update() и индивидуальное обновление полей объекта через его методы. Подготовьтесь, это будет интересно!

Основы обновления данных

Обновление данных в Django можно выполнить двумя способами:

  1. Обновить конкретный объект, изменяя его поля и сохраняя изменения.
  2. Массово обновить записи через метод update().

Каждый из этих подходов имеет свои преимущества и ограничения. Давайте рассмотрим оба варианта подробнее.

Индивидуальное обновление объекта

При работе с конкретным объектом мы можем обновить его поля просто назначив им новые значения, а затем вызвав метод .save(). Вот как это выглядит:

from myapp.models import Product

# Предположим, у нас есть продукт с именем "Молоко"
product = Product.objects.get(name="Молоко")
product.price = 60.99  # Обновляем цену
product.save()  # Сохраняем изменения в базу данных

Обратите внимание, что метод save() обязательно должен быть вызван, иначе изменения просто не попадут в базу. Django не будет сохранять объект "автоматически".

Пример: добавление скидки

Допустим, у нас есть модель Product с полями name и price. Мы хотим добавить скидку в 10% к товару, если его цена превышает 100:

product = Product.objects.get(name="Смартфон")
if product.price > 100:
    product.price *= 0.9  # Вычитаем 10%
    product.save()  # Сохраняем обновленное значение

Массовое обновление данных

Если нужно обновить сразу несколько записей, на помощь приходит update(). Этот метод обновляет поля всех записей, попавших в QuerySet, в один SQL-запрос. Это особенно полезно для больших объемов данных, так как он работает быстрее, чем обновление объектов по одному.

Вот как это делается:

from myapp.models import Product

# Устанавливаем скидку 5% на все товары, цена которых выше 500
Product.objects.filter(price__gt=500).update(discounted=True)

Что происходит внутри?

Метод update() генерирует один SQL-запрос, который обновляет все записи, соответствующие условию. Например, строка выше будет преобразована в SQL, подобный этому:

UPDATE your_table_name SET discounted = True WHERE price > 500;

Этот подход отлично подходит для массовых изменений, но он не вызывает метод save() у объектов. Это значит, что никакая дополнительная логика, связанная с save(), не будет выполнена.

Сохранение изменений в Django ORM

После обновления объекта нужно сохранить изменения в базу данных. В случае индивидуального объекта используется метод save().

Порядок сохранения:

  1. Найдите объект в базе данных с помощью QuerySet (get() или filter()).
  2. Измените нужные поля.
  3. Вызовите метод save().

Пример с добавлением описания продукту:

product = Product.objects.get(name="Хлеб")
product.description = "Мягкий и свежий хлеб из пекарни."
product.save()

Если вы забудете вызвать .save(), то изменения останутся только на уровне объекта в памяти и никак не отразятся в базе данных.

Особенности использования update()

Метод update() позволяет обновлять сразу несколько объектов одной командой. Это делает его быстрым и удобным инструментом, особенно для больших объемов данных.

Пример массового изменения поля:

# Все товары дешевле 100 рублей мы делаем "акционными"
Product.objects.filter(price__lt=100).update(is_promotion=True)

Важные особенности update():

  • Он не вызывает метод save(), следовательно, не выполняется дополнительная логика и не срабатывают сигналы модели.
  • Вы не можете использовать методы модели в выражении update(), только значения для полей.

Пример: массовое повышение цены

Если мы хотим увеличить цену всех товаров на 10%, то можем сделать это с update() и использованием F-объектов (о которых мы говорили в предыдущих лекциях):

from django.db.models import F

# Увеличиваем цену на 10% для всех товаров
Product.objects.update(price=F('price') * 1.1)

Этот пример генерирует SQL-запрос, который обновляет цену прямо в базе данных, не загружая объекты в память.

Особенности и подводные камни

Обновление данных кажется простым процессом, но есть нюансы, о которых стоит помнить:

  1. Ленивая загрузка QuerySet: метод update() работает прямо с QuerySet, не загружая объекты в память. Это хорошо для производительности, но внимание к деталям важно.

  2. Не вызывается save(): дополнительные проверки или сигналы, завязанные на метод save(), не сработают. Если вам нужно это поведение, обновляйте записи по одной.

  3. Предосторожности при массовом обновлении: перед вызовом update() убедитесь, что ваши фильтры достаточно узкие, чтобы случайно не обновить все записи в таблице.

Практическое применение

Допустим, мы разрабатываем интернет-магазин. Вот несколько практических примеров:

Пример 1: обновляем статус заказа Когда заказ выполнен, мы можем изменить его статус на "завершен".

from shop.models import Order

order = Order.objects.get(pk=1)
order.status = "Завершен"
order.save()

Пример 2: массовое обновление

Если мы проводим акцию "Черная пятница", все товары получают скидку 20%:

# Уменьшаем цену всех товаров на 20%
from django.db.models import F

Product.objects.update(price=F('price') * 0.8)

Пример 3: оптимизация через update()

Массовое обновление всех заказов, которые были отправлены более недели назад:

from django.utils.timezone import now
from datetime import timedelta

Order.objects.filter(date_sent__lt=now() - timedelta(days=7)).update(status="Архивирован")

Заключение темы

На этом этапе вы овладели навыками обновления данных в Django: от индивидуального изменения объектов и сохранения их через save() до массового обновления через update(). Выбор метода зависит от контекста и потребностей вашего проекта. На практике эти знания пригодятся везде: от изменения информации о пользователях до управления каталогами продуктов в e-commerce приложениях. Не забывайте экспериментировать и тестировать обновления на запросах, чтобы лучше понимать их влияние!

В следующей лекции мы продолжим углубляться в CRUD-операции и узнаем, как кроме обновления, удалять данные из базы безопасно и эффективно.

1
Задача
Модуль 3: Django, 8 уровень, 4 лекция
Недоступна
Массовое обновление данных
Массовое обновление данных
1
Задача
Модуль 3: Django, 8 уровень, 4 лекция
Недоступна
Обновление объекта с учетом логики в методе save()
Обновление объекта с учетом логики в методе save()
3
Опрос
CRUD-операции, 8 уровень, 4 лекция
Недоступен
CRUD-операции
CRUD-операции
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ