I’m having trouble with a post_save signal when using Admin. For background, I have a User extension model that uses a many-to-many relationship for user follows. But, I don’t want users to follow themselves. So, I created the following receiver:
@receiver(post_save, sender = UserInfo)
def check_self_follow(sender, instance, created, **kwargs):
logger.debug('Just saved %s', str(instance))
logger.debug('instance id is %s', instance.id)
logger.debug('users_followed %s', instance.users_followed.all())
for follow in instance.users_followed.all():
logger.debug('follow id is %s', follow.id)
if follow.id == instance.id:
logger.debug("Removing %s from follow links for %s", str(follow), str(instance))
instance.users_followed.remove(follow)
I also have 2 helper functions defined in the UserInfo model class:
def follow_user(self, user: "UserInfo"):
"""Create a link for the specified user to follow the user input."""
logger.debug("creating link for user %s following %s", self.username, user.username)
self.users_followed.add(user)
self.save()
logger.debug("Follow link creation successful")
def get_users_followed(self):
"""Return a list of UserInfo objects for all users followed by this user"""
users_followed = [list for list in self.users_followed.all()]
logger.debug("getting list of users followed for user %s: %s", self.username, users_followed)
return users_followed
This works fine when I’m working in the shell, I see something like this:
>>> betty.follow_user(Betty)
creating link for user betty following Betty
Just saved Betty
instance id is 1
users_followed <QuerySet [UserInfo("betty","betty"), UserInfo("joe","joe")]>
follow id is 1
Removing betty from follow links for Betty
follow id is 3
Follow link creation successful
This is working correctly, as shown in the shell:
>>> betty.get_users_followed()
getting list of users followed for user betty: [UserInfo("joe","Joe")]
[UserInfo("joe","Joe")]
But when I do a similar thing in the Django Admin console, I see the following:
Just saved Betty
instance id is 1
users_followed <QuerySet [UserInfo("joe","joe")]>
follow id is 3
And the shell shows:
>>> betty.get_users_followed()
getting list of users followed for user betty: [UserInfo("betty","betty"), UserInfo("joe","Joe")]
[UserInfo("betty","betty"), UserInfo("joe","Joe")]
It’s as if admin is calling check_self_follow in pre_save instead of post_save. This is my first whack at Django, and I’m mystified. Is there some difference with signals in admin?