Django model ManyToManyField.add is not working
I have a model named TopicRoom and it has a field called creator which is a foreign key to the user model. And a many to many field called members which is a many to many rel to the user model
@receiver(post_save, sender=models.TopicRoom)
def add_topic_room_creator_as_a_member(instance, created, **kwargs):
if created:
print("added creator", instance.creator, instance)
instance.members.add(instance.creator)
print(instance.members.all())
When I create a new instance in the admin panel it prints this
added creator bob@gmail.com TopicRoom object (24)
<QuerySet [<User: bob@gmail.com>]>
but when I view the model in the admin panel it shows that there are no members. And when I retrieve the model from the django manage.py shell, that also shows that there are no members for that object instance
>>> TopicRoom.objects.get(id=24).members.all()
<QuerySet []>
This is a very common issue with post_save Django signals depending on how you are handling data and data structures.
But the good thing is this can be solved easily using transaction.on_commit() method. Ref: Performing actions after commit
Update your add_topic_room_creator_as_a_member function like this:
from django.db import transaction
@receiver(post_save, sender=models.TopicRoom)
def add_topic_room_creator_as_a_member(sender, instance, created, **kwargs):
if created:
def add_member():
instance.members.add(instance.creator)
print(instance.members.all())
transaction.on_commit(add_member)
transaction.on_commit makes sure your function runs after the successful completion of the current transaction.
Try using:
instance.save()
after
print(instance.members.all())
Did you set relative names for both fields? because Django creates a default relative name "model_set. In your case, you are using the User model two times.