Reputation: 77
I have Post model, that has a field likes_total on it. I only want a user to be able to like a post once, but the code for this in the view is not working. here is the code:
views.py
def like(request, post_id, group_id):
group = get_object_or_404(Group, pk= group_id)
post = get_object_or_404(Post, pk= post_id)
likers = []
if request.method == 'POST':
if request.user in likers:
return render(request, 'groups/detail.html', {'group':group, 'error': "you have already liked this post"} )
else:
post.likes_total += 1
post.save()
likers.append(request.user)
return redirect('/groups/' + str(group_id) )
# post.save()
else:
return render(request, 'groups/detail.html', {'group':group})
this code seems right to me, cant tell what the problem is.. any help would be really appreciated!
Upvotes: 0
Views: 99
Reputation: 476709
You define a list named likers
in the like
function. That means that each time someone calls the like
function, you construct a new and empty list.
You could construct the list outside the function, but this will not help either. In fact the only data that you can consider persistent (the data that you can insert/modify/delete such that the next call sees this differences) is in the database.
As a result you should let the database store the people who like the post, by for example adding a ManyToManyField
to the Post
model that refers to the users that liked to post. So you should edit the model:
class Post(Model):
likers = ManyToManyField(User)
# some other fields
likes_total = IntegerField()
Now we can add the user that likes the post to the many-to-many relation:
def like(request, post_id, group_id):
group = get_object_or_404(Group, pk= group_id)
post = get_object_or_404(Post, pk= post_id)
if request.method == 'POST':
if request.user in post.likers.all():
return render(request, 'groups/detail.html', {'group':group, 'error': "you have already liked this post"} )
else:
post.likes_total += 1
post.likers.add(request.user)
post.save()
return redirect('/groups/' + str(group_id) )
else:
return render(request, 'groups/detail.html', {'group':group})
Another improvement that you can make is using reverse
to generate urls, instead of constructing URLs yourself.
Upvotes: 0
Reputation: 408
Your likers
list isn't persisted anywhere and it's always initialized to an empty list, so the request.user
will never be in the list.
You should edit your model so that each of your Post
objects have a list of users that liked it, and then you can persist, update and check that list to ensure that each user likes each post once at most.
Upvotes: 0
Reputation: 97
Every time your function is called you set likers to be empty. Instead it should be an attribute of the post.
Upvotes: 1