JawsIk
@JawsIk
Python Django, Lua, ЧПУ-станки(ArtCam, Aspire)

Как в Django массово изменять значение (например увеличить цену на % или значение)?

Итак существует модель Product (в примере упрощена):
class Product(models.Model):
    title = models.CharField(max_length=100, verbose_name="Название изделия", unique=True)
    category = models.ForeignKey(Category, on_delete=models.PROTECT, verbose_name="Категория")
    price_mp = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)
    price_kp = models.DecimalField(max_digits=9, decimal_places=2, default=0.00)


В ней около 25 тыс. записей. И вот заказчик говорит, что мол нужно время от времени корректировать цену.
А например сегодня (вводная задача) в изделиях у которых категория под номером 20, нужно увеличить цену МП на 5%,
а так же у всех изделий каталога уменьшить цену КП на 250 руб.

Я сделал форму и страницу, из которой принимаю данные. Я их проверяю, если надо меняю тип и в итоге получаю следующее:
act = 'plus' # или minus, это собственно действие
val = 5 # или 250 по второму заданию
unit = 'percent' # или ruble
target = 'price_category' # или price_all, чтобы знать менять для категории или везде
category = 20 # ну или то, что пришло из формы
type_price = 'all' # или 'mp' или 'kp'


Далее я нашёл вот этот пример, где показано использование подзапроса, но там используется некий AVG, который меня запутывает и я не пойму, а мне так или как-то иначе сделать. Подскажите чего написать то? Сейчас у меня это выглядит как-то так:
from django.db.models import OuterRef, Subquery # это вверху
...
           # хочу выполнить первую вводную, т.е. price_mp в категории
            Product.objects.filter(category=20).update(
                price_mp = Subquery(
                    Product.objects.filter(id=OuterRef('id')).annotate( # надо ли мне вообще annotate
                        'price_mp' + 'price_mp' * val / 100 # в общем я как-то запутался 
                    )
                ),
                # price_kp = 2
            )


Не могу понять простую вещь, как везде взять и изменить цену относительно существующих значений. Люди добрые, ну подскажите.

p.s. я знаю, что можно через цикл, но боюсь будет вешать сервер при обновлении цен.
  • Вопрос задан
  • 1219 просмотров
Решения вопроса 1
Shmele
@Shmele
Python developer
Похоже, Вам могут помочь F-выражения:
https://docs.djangoproject.com/en/2.2/ref/models/e...

Product.objects.filter(category=20).update(F('price_mp') + F('price_mp') * val / 100)


Обновит цену у всех выбранных продуктов, использовав для вычисления новой цены, текущую - F('price_mp').
Будет работать одним запросом, на уровне базы данных.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Conditional expression должны помочь.
Ответ написан
Комментировать
@MAGistr_MTM
Учусь программировать
Винеси задание в отдельную таску. И запускай ее асинхронно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы