example python django django-models django-signals

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()