ZANIN блог
Контакты
Крути вниз
Фильтр по:
Категории
//Post title

Заметка - Django Signals: пример post_save

11 Июл 2020Категория : Django

Заметка - Django Signals: пример post_save

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

Все сигналы в Django это экземпляры класса Signal. В самом Django много встроенных сигналов, но приведу пример сигналов, отправляемых подсистемой доступа к базам данных, которые объявлены в модуле

django.db.models.signals

 

Поэтому импортируем:

from django.db.models.signals import post_save

from django.dispatch import receiver

 

Приведу пример сигнала post_save, который отправляется после сохранения модели, то есть после выполнения метода save(). Если еще проще, то при сохранении одной модели, посылается сигнал и происходит действие привязанное на этот сигнал, в моем примере это сохранение другой модели.

В примере есть 2 модели: модель продукта или товара в интернет-магазине, и модель размеров продукта. У каждого размера продукта своя цена, а у продукта есть базовая цена и размер скидки в процентах. Как только мы сохраняем продукт со скидкой или меняем размер скидки в продукте, то должно происходить изменение цен у размеров. В примере часть полей отсутствует.

class Product(models.Model):

        name = models.CharField(max_length=200, verbose_name='Имя')
        slug = models.SlugField(max_length=200, verbose_name='(Ссылка)', blank=True)
        price = models.PositiveIntegerField(null=True, verbose_name='Цена')
        sale = models.PositiveIntegerField(default=0, blank=True, null=True, verbose_name='Размер скидки')
        new_price = models.PositiveIntegerField(blank=True, null=True, help_text='Вычисляется само при сохранении', verbose_name='Новая цена')

 

class Sizes(models.Model):

        product = models.ForeignKey('Product', on_delete=models.CASCADE, verbose_name='Продукт')
        height = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='Высота')
        width = models.PositiveSmallIntegerField(null=True, blank=True, verbose_name='Ширина')
        price = models.PositiveIntegerField(default=0, verbose_name='Цена')
        saleprice = models.PositiveIntegerField(blank=True, null=True, help_text='Вычисляется само при сохранении', verbose_name='Цена размера по скидке')

        # Функциональное поле, для определения цены со скидкой по всем размерам
        @property
        def new_price_with_sale_on_all_size(self):
                saleprice = self.price
                sizeproduct = self.product
                if sizeproduct.on_sale:
                        percent = Decimal((100 - sizeproduct.sale)/100)
                        saleprice = self.price * percent.quantize(Decimal('1.00'))
                return saleprice

        def save(self, *args, **kwargs):
               self.saleprice = self.new_price_with_sale_on_all_size
               super(Sizes, self).save(*args, **kwargs)

 

# Сигнал, если товар сохранился со скидкой, то пересохраняем цены у размеров
@receiver(post_save, sender=Product)
def update_price_for_size(sender, instance, **kwargs):
        product = Product.objects.get(name=instance)
        savesize = Sizes.objects.filter(product=product)
        for ss in savesize:
                ss.save()

  • 687

Готовы заказать проект?

© ZANIN 2019 / All rights reserved.
Контакты
Close