Issue
my simplified problem is below:
i have a model like this:
class Alert(models.Model):
ALERT_CHOICES = [("email","email"),("sms","sms"),("notif","notif")]
name = models.CharField(max_length = 50)
owner = models.ForeignKey(User , on_delete=models.CASCADE)
coins = models.ManyToManyField(Coin,blank=True)
when an object of Alert like alert changes. i want to print number of coins that connected to alert after change in this method:
@receiver(post_save, sender=Alert)
def handle_alert_save(sender, instance, **kwargs):
coins = instance.coins.all()
print(len(coins))
Unfortunately! it prints number of coin before change alert. i want after change the object. in other words post_save signal is exactly equal to pre_save.
for example when i have 2 connected coin to aler and i change it to 5. it prints 2!
i try all other signals like pre_save and pre_delete and pre_migrate and post_migrate.
Solution
No, it does trigger the signal after saving the Alert
, but the many-to-many fields are saved after saving the Alert
, so at that time, there are indeed still no coins updated. This is one of the many reasons not to use signals in the first place [django-antipatterns].
You could use the m2m_changed
signal [Django-doc] instead:
from django.db.models.signals import m2m_changed
@receiver(m2m_changed, sender=Alert.coins.through)
def handle_alert_save(sender, instance, **kwargs):
coins = instance.coins.all()
print(len(coins))
But personally, I think signals are often not a good idea and should be used as last resort. It might be more robust to simply add a function to do the logic, and trigger this in the views where you alter the .coins
of an Alert
instance.
Answered By - willeM_ Van Onsem
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.