How to get count and show in template - Django

I was able to get the mutual friends from each users and display each mutual friends image on my template as seen in the attached image to this question. The problem now is that I was not able to get the count, like count and length is not working on template. How can I get it done?

enter image description here

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,blank=True,null=True) 
    profile_pic = models.ImageField(upload_to='UploadedProfilePicture/', default="ProfileAvatar/avatar.png", blank=True)
    following = models.ManyToManyField(
        'Profile',  # Refers to the User model itself
        symmetrical=False,  # If A follows B, B doesn't automatically follow A
        related_name='followers',  # Reverse relationship: get followers of a user
        blank=True,
    )


def FollowingView(request):
    page_title = "Following"

    # All account users
    profile_users = Profile.objects.exclude(
        Q(user=request.user))

    # Mutual Followers
    all_following = request.user.profile.following.values_list('pk', flat=True)
    mutual_followers = Profile.objects.filter(pk__in=all_following)


Template:

{% for users in profile_users %}

# List of users
<p>{% users.user %}</p>

{% for user_following in mutual_followers %}
  {% if user_following in users.following.all %}
  <img src="{{ user_following.user.profile.profile_pic.url }}" class="hover-followers-img"/>

  {{ user_following.count }} # Not getting count

  {% endif %}
  {% endfor %}

{% endfor %}

The problem now is that I was not able to get the count, like count and length is not working on template.

Strictly speaking you can get .count() or |length working in the template, but you shouldn't, Indeed, Django's template language is deliberately restricted to prevent calling methods with parameters or subscripting with arbitrary keys. The Jinja template language offers this, and you can use this instead, but that is not a good idea either.

The reason this is not (easy) to do in the template is because it does not belong in the template. The templates should deal with rendering logic: they are given data that is filtered, aggregated, and combined by the view, and the template should not do any of this, except formatting the data is has been provided in a nice looking way. Here the template filters, this will make it harder to reuse the logic somewhere else (for example if you want to use two templates by the same view), and work less efficient, since Django's template engine is far from efficient.

from django.db.models import Count, Prefetch, Q


def FollowingView(request):
    page_title = 'Following'

    # All account users
    profile_users = (
        Profile.objects.exclude(Q(user=request.user))
        .annotate(
            nmutual=Count(
                'following', filter=Q(following__followers__user=request.user)
            )
        )
        .prefetch_related(
            Prefetch(
                'following',
                Profile.objects.filter(followers__user=request.user),
                to_attr='mutual_friends',
            )
        )
    )
    return render(request, 'my_template.html', {'profile_users': profile_users})

and then render this as:

{% for users in profile_users %}
  <p>{% users.user %}</p>

  {% for user_following in user.mutual_freinds %}
    <img src="{{ user_following.user.profile.profile_pic.url }}" class="hover-followers-img"/>
  {% endfor %}
  <b>{{ user.nmutual }}</b> # Not getting count
{% endfor %}

Note: Functions are normally written in snake_case, not PascalCase, therefore it is advisable to rename your function to following_view, not FollowingView.

Вернуться на верх