Filter lists in template if

Hello there!

I am still working on my twitter-like project to learn django.

What I want to do:
• Have a timeline-view that get’s a list of all posts and shows them chronologically sorted: ✓
• Each post should have a like button attached: ✓
• Each like button should either show “like” or “unlike”, depending if it has already been liked: x

There is my issue. I have a timeline view that renders the timeline.html template. It gets all the posts (and right now also all likes) from my database. I want to check if a post has been liked already, so something along the lines of:

{% if len(Likes.objects.filter(post_id = xxx, user_id= yyy)) == 0 %}

I already know that this particular attempt won’t work, but is there any way of matching both lists (posts, likes) within the template?

I would recommend that you resist the urge to put this kind of code into a template. It will be hard to test and hard to maintain in the long term.

I think what you are looking for is aggregration. Check out the Aggregation topic. Aggregation allows you to do count queries on other models (and other things) and attach them to records on a queryset (e.g., adding like_count to a Post). If you do that outside of templates, then the template logic can be much simpler.

{% for post in posts %}
    {% if post.like_count %}
        Unlike button here
    {% else %}
        Like button here
    {% endif %}
{% endfor %}
1 Like

Thank you for this direction, I am currently reading up on Aggregation and Annotation. I was also able to annotate like_count to my posts, but I need to be more specific.
Likes have to be filtered by user id of the viewing user so that I can decide if this specific user has or has not liked a post. I will try to get that done. My first idea was to use jquery to send a request per post to a “/like/verify” url that returns true or false depending on the current state.

I will need to use some ajax nonetheless to change the button text when it is clicked without reloading the page, but on load your concept looks really promising.
Thanks again!