save method or post_save signal is not being called while through model instance of a ManyToManyField is getting created

37 views Asked by At

I have a Post model in my Django app. It has a many-to-many relationship with User model through the UserTag model named user_tags.

class Post(models.Model):
    id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.TextField()
    user_tags = models.ManyToManyField(User, through=UserTag)

class UserTag(models.Model):
    id = models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, blank=True)
    comment = models.ForeignKey(Comment, on_delete=models.CASCADE, null=True, blank=True)

    def save(self, *args, **kwargs):

        print("#### user tagged ##### - save method")
        print(self.user)

        return super().save(*args, **kwargs)

@receiver(post_save, sender=UserTag)
def user_tagged_signal(sender, instance, created, **kwargs):

    if not created:
        return
    
    print("#### user tagged ##### - post save signal")
    print(instance.user)

When I tag a user to a post as follows:

post.user_tags.set(users)

or

post.user_tags.add(user)

UserTang model instance gets created but save method or post_save signal of the UserTag model is not getting called.

I want to send notification to the user and remove the notification depending on the creation and deletion of the UserTag instance.

Is there anything I'm doing wrong or can you suggest me a solution?

1

There are 1 answers

0
CoffeeBasedLifeform On

RelatedManager.add does not call the save method of the through model. Neither does set (it uses add under the hood). Instead these methods use QuerySet.bulk_create which directly inserts into the table.

Using add() with a many-to-many relationship, however, will not call any save() methods (the bulk argument doesn’t exist), but rather create the relationships using QuerySet.bulk_create(). If you need to execute some custom logic when a relationship is created, listen to the m2m_changed signal, which will trigger pre_add and post_add actions.

https://docs.djangoproject.com/en/5.0/ref/models/relations/#django.db.models.fields.related.RelatedManager.add