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)