Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-viewsdjango-signals

Why my "friends_list" remains empty when my Django signal is triggered?


I am using a Django post_save signal to modify the Database content of Budget. In my response I get the friendsList filled with the user IDs, but when I use post_save signals and query and store it in friends_list I see that the list remains empty.

My response:

{
    "id": 5,
    "amount": 100,
    "budgetForSplitPay": 1,
    "friendsList": [
      2,
      3
    ]
  }

My post_save signal code:

@receiver(post_save, sender=SplitPayBudget)
def post_save_splitpay_amount(sender, instance, created, **kwargs):
    Budget.objects.filter(user=instance.budgetForSplitPay.user).update(budgetofUser=F('budgetofUser') - instance.amount)
    friends_list = instance.friendsList.all()

    for friend in friends_list:
        Budget.objects.filter(user=friend.user).update(budgetofUser=F('budgetofUser') - instance.amount)

My model:

class SplitPayBudget(models.Model):
    budgetForSplitPay = models.ForeignKey(Budget, on_delete=models.CASCADE, related_name='budgetForSplitPay')
    friendsList = models.ManyToManyField(Budget, related_name='friendsList', blank=True)
    amount = models.IntegerField(default=0)

    def __str__(self):
        return str(self.budgetForSplitPay.user)

My API call body which triggers this signal:

{
  "budgetForSplitPay": "1",
  "amount": 100,
  "friendsList": [2, 3]
}

My serializer:

class SplitPayBudgetSerializer(ModelSerializer): # Actually a TransactionSerializer
    class Meta:
        model = SplitPayBudget
        fields = '__all__'

I want a solutions by which my friends_list should be initialised with [2, 3].

Thank You.

I tried using friends_list = instance.friendsList.all() but the instance.friendsList.all() remains empty.


Solution

  • So I solved my problem by taking @Lax_Sam's hint. Used m2m_changed and post_add action.

    Signal Code:

    @receiver(post_save, sender=SplitPayBudget)
    def post_save_splitpay_amount(sender, instance, created, **kwargs):
        Budget.objects.filter(user=instance.budgetForSplitPay.user).update(budgetofUser=F('budgetofUser') - instance.amount)
    
        
    @receiver(m2m_changed, sender=SplitPayBudget.friendsList.through)
    def update_budget_for_splitpay(sender, instance, action, **kwargs):
        if action == 'post_add':
            for friend in instance.friendsList.all():
                Budget.objects.filter(user=friend.user).update(budgetofUser=F('budgetofUser') - instance.amount)