Reputation: 2189
I have an Article
model which I fetch from when a user successfully logs in:
articles = Article.objects.all()
I also have Likes
model which has user_id
and article_id
to record articles users have liked.
articles_liked = Likes.objects.values_list('article_id', flat = True)
users_who_liked = Likes.objects.values_list('user_id', flat = True)
The article_id
gives a list of article users have liked while users_who_liked
gives a list of users who liked those articles as shown below:
articles_liked = [4, 3, 5, 6, 10]
users_who_liked = [1, 13, 15, 16, 110]
What I want to achieve is to be able to tell if a particular post is already liked by the logged in user in my template.
{% for article in articles %}
<p>{{article.content}}</p>
{% if this_user_id in users_who_liked and article.id in articles_liked %}
<p class = 'likes'> 2 </p>
{% else %}
<p class = 'likes already_liked'> 2 </p>
{% endif %}
{% endfor %}
Let's assume this_user_id = 1
and the articles he/she likes is 4
, the if
statement returns True
for all the articles and the else
block never get to be executed.
How can I do this the right way?
Upvotes: 0
Views: 563
Reputation: 174624
As your Likes object has a reference to both Users and Articles, why not exploit this in your view? That way you control the logic in your view and template just becomes a simple if statement:
def some_view(request):
articles = Article.objects.all()
user = request.user
article_list = []
for a in articles:
# Create a tuple, with a flag if the user has liked this article or not.
article_status = (Likes.objects.filter(article_id=a.pk, user_id=user.pk).exists(), a,)
article_list.append(article_status)
return render(request, 'template.html', {'articles': article_list})
Now, in your template you have the following:
{% for liked,article in articles %}
{% if liked %}
<strong>You already liked this article!</strong>
{% endif %}
{{ article }}
{% endfor %}
Upvotes: 0
Reputation: 3867
Your variables articles_liked
and users_who_liked
are not correlated to each other. They always contain all liked articles and all users who liked, but between them there is no relation in your template context which you can rely on.
Therefore your if
statement will always return True
for every user who liked any article which has been liked by at least one user.
Assuming from your question that Like
has a foreign key (Django docs) to User
and a foreign key to Article
you could just add a filter to your articles_liked
assignment to only retrieve likes from the current user:
articles_liked = Likes.objects.filter(user_id=this_user_id).values_list('article_id', flat = True)
Then in your template you can simply check if the current article is in this list:
{% for article in articles %}
<p>{{article.content}}</p>
{% if article.id in articles_liked %}
<p class = 'likes'> 2 </p>
{% else %}
<p class = 'likes already_liked'> 2 </p>
{% endif %}
{% endfor %}
Upvotes: 1