Массовая корректировка цен для всех продуктов

Перенесите уменьшение в один UPDATE через F и Decimal. Но заранее определите округление и учтите, что QuerySet.update не вызывает save и сигналы.

Короткий ответ

Что ответить на собеседовании

Перенесите уменьшение в один UPDATE через F и Decimal. Но заранее определите округление и учтите, что QuerySet.update не вызывает save и сигналы.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо проверить, правильно ли реализована логика изменения стоимости каждого товара в базе данных: цена снижается на 5 %, после чего вызывается метод save() для каждой записи. Оцените, возможно ли реализовать данную операцию более эффективно.

products = Product.objects.all()

for product in products:
    product.price *= 0.95
    product.save()

Ответ

Перенесите уменьшение в один UPDATE через F и Decimal. Но заранее определите округление и учтите, что QuerySet.update не вызывает save и сигналы.

from decimal import Decimal
from django.db.models import F

Product.objects.update(price=F('price') * Decimal('0.95'))

Для DecimalField множитель float из исходника может вызвать ошибку смешения типов; для денежных сумм нужен точный десятичный коэффициент. Итоговое округление зависит от типа столбца и СУБД — закрепите правило до массового изменения.

F вычисляет от актуальной цены в БД и не загружает все объекты в Python. Если важны переопределённый save, сигналы или сложные расчёты, потребуется другой путь. Повторный запуск снова снизит цены: для разовой акции нужен учёт её применения и резервная копия/снимок исходных значений.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее