I simulate Instagram app.
I have Followers, Actions models.
Each action is done on a “follower”.
Many actions can point to one follower.
class Follower(models.Model): identifier = models.BigIntegerField( _("identifier"), unique=True, null=False, blank=False) class ActionModel(models.Model): target = models.ForeignKey(Follower, verbose_name=_("Target"), on_delete=models.CASCADE) # username of the done-on action user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, ) # django user that performed the action is_followed_back = models.BooleanField(_("Followed Back"), null=True, blank=True) # is target followed back
Admin panel:
# Custom Admin for Follower model class FollowerAdmin(AdminAdvancedFiltersMixin, NumericFilterModelAdmin, SpecialActions): ... # Private method to count been_followed_counter def _get_been_followed_count(self, obj): return obj.been_followed_count _get_been_followed_count.short_description = 'Been Followed Count' _get_been_followed_count.admin_order_field = 'been_followed_count' # Private method to count follow_back_count def _get_follow_back_count(self, obj): return obj.follow_back_count _get_follow_back_count.short_description = 'Follow Back Count' _get_follow_back_count.admin_order_field = 'follow_back_count'
I then override the get_queryset for followers:
# Override queryset method to add count's def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.annotate( been_followed_count=Count('actionmodel', filter=Q(actionmodel__user=request.user)) ).annotate( follow_back_count=Count( 'actionmodel', filter=Q(actionmodel__user=request.user) & Q(actionmodel__is_followed_back=True) ) )
I get really strange results in the admin panel: no search in panel
USERNAME : lior___shahar
BEEN FOLLOWED COUNT:5
FOLLOW BACK COUNT:5
This is the True VALUE in actions: Value in action
But once I do SEARCH in FOLLOWERS for the username: After Search
USERNAME : lior___shahar
BEEN FOLLOWED COUNT:320
FOLLOW BACK COUNT:320
…
I don’t get what is wrong.
Advertisement
Answer
Try adding distinct=True
to the count annotation.
been_followed_count=Count('actionmodel', filter=Q(actionmodel__user=request.user), distinct=True)