M
M
Maxim Zubenko2019-08-09 15:43:02
Django
Maxim Zubenko, 2019-08-09 15:43:02

How to bulk change a value in Django (for example, increase the price by % or value)?

So there is a Product model (simplified in the example):

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)

It contains about 25 thousand entries. And now the customer says that they say you need to adjust the price from time to time.
And for example today ( introductory task ) in products with category number 20, you need to increase the price of MP by 5%,
as well as for all products in the catalog, reduce the price of KP by 250 rubles.
I made a form and a page from which I receive data. I check them, if necessary I change the type and as a result I get the following:
act = 'plus' # или minus, это собственно действие
val = 5 # или 250 по второму заданию
unit = 'percent' # или ruble
target = 'price_category' # или price_all, чтобы знать менять для категории или везде
category = 20 # ну или то, что пришло из формы
type_price = 'all' # или 'mp' или 'kp'

Next, I found this example , which shows the use of a subquery, but some AVG is used there, which confuses me and I don’t understand, but I have to do it one way or another. Tell me what to write then? Now it looks something like this for me:
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
            )

I can’t understand a simple thing, how to take and change the price everywhere relative to existing values. Good people, well tell me.
ps I know that it is possible through a cycle, but I'm afraid the server will hang up when prices are updated.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Shmele, 2019-08-09
@JawsIk

Looks like F-expressions can help you:
https://docs.djangoproject.com/en/2.2/ref/models/e...
Updates the price of all selected products using the current price F('price_mp') to calculate the new price.
Will work with one request, at the database level.

S
Sergey Gornostaev, 2019-08-09
@sergey-gornostaev

Conditional expression should help.

Y
Yura Khlyan, 2019-08-09
@MAGistr_MTM

Vine the task in a separate task. And run it asynchronously.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question