# A lógica é mantida dentro de um método da classe
# arquivo 'models.py'
from django.db.models.signals import post_save
class Product(TimestampableMixin):
# ...
@classmethod
def increment_stock(cls, sender, instance, **kwargs):
product = instance.product
product.stock += instance.amount
product.save()
class StockEntry(TimestampableMixin):
# ...
post_save.connect(Product.increment_stock, sender=StockEntry)
# A lógica é mantida num método fora da classe
# arquivo 'models.py'
from django.db.models.signals import pre_delete
from django.dispatch import receiver
@receiver(pre_delete, sender=Banner) # Banner é o model
def handler_pre_delete(sender, instance, **kwargs):
os.remove(instance.imagem.path)
print('sender', sender)
Doc auxiliar: https://docs.djangoproject.com/en/2.2/ref/applications/#configuring-applications\ A lógica é mantida dentro do arquivo de configuração em 'apps.py'. E deve ser chamada a partir do settings puxando pela classe que herda de AppConfig.
# 'stock/signals.py'
def increment_stock(sender, instance, **kwargs):
product = instance.product
product.stock += instance.amount
product.save()
# Maneira ~1
# post_save.connect(increment_stock, sender=StockEntry)
# Maneira ~1
# lógica em 'app.py' no método 'ready'
No 'apps.py' podemos configurar de 2 maneiras
# 'apps.py'
from django.apps import AppConfig
class StockConfig(AppConfig):
name = 'stock'
def ready(self):
# Maneira ~1
# para manter essa maneira veja os comentários do arquivo 'signals.py'
# from stock import signals
# Maneira ~2
from stock.signals import increment_stock
from django.db.models.signals import post_save
stock_entry_model = self.get_model(model_name='StockEntry')
post_save.connect(increment_stock, sender=stock_entry_model)
Agora em settings.py, chame a app de forma correta.
# ...
INSTALLED_APPS = [
# ...
'stock.apps.StockConfig',
]
Em 'signals.py'
from django.dispatch.dispatcher import Signal
signal_personalizado_product_stock_changed = Signal()`
def increment_stock(sender, instance, created, **kwargs):
if created is True:
product = instance.product
product.stock += instance.amount
product.save()
# Adiciona
signal_personalizado_product_stock_changed.send(sender=None, instance=product)
def send_mail_stock_max_overload(sender, instance, **kwargs):
if instance.stock > instance.stock_max:
# Enviar email
pass
post_save.connect(increment_stock, sender=StockEntry)
# Adiciona
signal_personalizado_product_stock_changed.connect(send_mail_stock_max_overload, sender=None)
https://docs.djangoproject.com/en/2.2/topics/signals/
https://docs.djangoproject.com/en/2.2/ref/signals/