python - example - Implementación de la señal Django post_save()
django signals example (3)
Tengo una pregunta sobre django.
Tengo ManyToMany Models aquí
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(default=0.0, max_digits=9, decimal_places=2)
stock = models.IntegerField(default=0)
def __unicode__(self):
return self.name
class Cart(models.Model):
customer = models.ForeignKey(Customer)
products = models.ManyToManyField(Product, through=''TransactionDetail'')
t_date = models.DateField(default=datetime.now())
t_sum = models.FloatField(default=0.0)
def __unicode__(self):
return str(self.id)
class TransactionDetail(models.Model):
product = models.ForeignKey(Product)
cart = models.ForeignKey(Cart)
amount = models.IntegerField(default=0)
Para 1 objeto de carro creado, puedo insertar tantos como el nuevo objeto TransactionDetail (el producto y la cantidad). Mi pregunta es. ¿Cómo puedo implementar el disparador? Lo que quiero es que cada vez que se cree un detalle de la Transacción, quiero que la cantidad de las existencias del producto se resta por el importe en el detalle de la transacción.
He leído sobre post_save () pero no estoy seguro de cómo implementarlo. tal vez algo como esto
cuando: post_save (TransactionDetail, Cart) #Cart objeto donde TransactionDetail.cart = Cart.id
Cart.stock -= TransactionDetail.amount
Personalmente, anularía el método save () de TransactionDetail y allí guardaría el nuevo TransactionDetail y luego ejecutaría
self.product.stock -= self.amount
self.product.save()
Si desea evitar que se maximum recursion depth exceeded
, entonces debe desconectar las señales antes de guardarlas dentro del controlador de señal. El ejemplo anterior (la respuesta de Kenny Shen) sería:
from django.db.models.signals import post_save
from django.dispatch import receiver
class TransactionDetail(models.Model):
# ... fields here
# method for updating
@receiver(post_save, sender=TransactionDetail, dispatch_uid="update_stock_count")
def update_stock(sender, instance, **kwargs):
instance.product.stock -= instance.amount
post_save.disconnect(update_stock, sender=TransactionDetail)
instance.product.save()
post_save.connect(update_stock, sender=TransactionDetail)
Esto se describe detalladamente en Desconectar señales para modelos y volver a conectar en django , con un ejemplo más abstracto y útil.
También vea: https://docs.djangoproject.com/en/2.0/topics/signals/#disconnecting-signals en los documentos de django.
Si realmente quiere usar señales para lograr esto, aquí está brevemente cómo,
from django.db.models.signals import post_save
from django.dispatch import receiver
class TransactionDetail(models.Model):
# ... fields here
# method for updating
@receiver(post_save, sender=TransactionDetail, dispatch_uid="update_stock_count")
def update_stock(sender, instance, **kwargs):
instance.product.stock -= instance.amount
instance.product.save()