@vikholodov

Как сделать поле суммы в модельке Django кастомизируемым?

В общем, total рассчитывается функцией get_cost(), которая суммирует значения других полей. Нужно чтобы результат функции можно было поправить руками из админки не трогая другие поля. Вопрос как это грамотно сделать?
class OrderItem(models.Model):
    order = models.ForeignKey('Order', related_name='items', on_delete=models.CASCADE)
    product = models.ForeignKey('Product', related_name='order_items', on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Цена')
    quantity = models.PositiveIntegerField(default=1, verbose_name='Количество')
    shipping_cost_pl = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Стоимость доставки по Польше')
    shipping_cost_ru = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Стоимость доставки в Калининград')
    total = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='Сумма')
    class Meta:
        verbose_name = 'Товар в заказе'
        verbose_name_plural = 'Товары в заказе'


    def __str__(self):
        return str(self.id)

    def get_cost(self):
        return ( (self.price + self.shipping_cost_pl + self.shipping_cost_ru ) * self.quantity)

    def save(self, *args, **kwargs):
        self.total = self.get_cost()
        super(OrderItem, self).save(*args, **kwargs)
  • Вопрос задан
  • 836 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Sovetnikov
технический директор pulsprodaj.ru
1. Сделайте страницу которая будет делать OrderItem.objects.filter(pk=order_item_id).update(total=33)
2. Переопределите у своего ModelAdmin save_model, примерно так (я не тестировал этот код):
def save_model(self, request, obj, form, change):
    if 'total' in form.changed_data:
        # В OrderItem.save обработайте параметр update_total
        obj.save(update_total=False)
    else:
        obj.save(update_total=True)

Тут проблемы могут возникнуть в зависимости от сложности вашего ModelAdmin, думаю при наличии inline может что-то пойти не так ...
3. Можно сделать надёжно и тупо:
def save_model(self, request, obj, form, change):
    if 'total' in form.changed_data:
        custom_total = obj.total
        super().save_model(request, obj, form, change)
        OrderItem.objects.filter(pk=obj.pk).update(total=custom_total)
    else:
        super().save_model(request, obj, form, change)
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы