我正在学习哈佛大学的在线课程 CS50W 并构建一个类似于 Twitter 的网络应用程序。 当用户看到帖子时,我需要根据用户喜欢或不喜欢向用户显示“喜欢”或“不喜欢”按钮。还有一个计数器显示到目前为止有多少用户喜欢该帖子。如果用户喜欢或不喜欢该帖子,我可以更新计数器,但我在显示或隐藏按钮的代码方面遇到问题。
这是我的代码:
模型.py
class Post(models.Model):
""" Model representing a post. """
user = models.ForeignKey(User, on_delete=models.CASCADE)
content = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
no_of_likes = models.IntegerField(default=0)
def __str__(self):
return f"Post {self.id} by {self.user.username} on {self.timestamp}"
class Like(models.Model):
""" Model representing a like. """
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user} likes {self.post}"
urls.py
path("", views.index, name="index"),
path("like/<int:post_id>", views.like, name="like"),
path("unlike/<int:post_id>", views.unlike, name="unlike"),
views.py
def index(request):
""" Home page. """
posts = Post.objects.all().order_by('-timestamp')
paginator = Paginator(posts, 5)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
likes = Like.objects.all()
# Make a list of liked posts.
liked_posts = []
try:
for like in likes:
if like.user.id == request.user.id:
liked_posts.append(like.post.id)
except:
liked_posts = []
return render(request, "network/index.html", {
"posts": posts,
"page_obj": page_obj,
"likes": likes,
"liked_posts": liked_posts,
})
@login_required
def like(request, post_id):
post = Post.objects.get(pk=post_id)
user = User.objects.get(pk=request.user.id)
like = Like.objects.create(user=user, post=post)
like.save()
# Update no of likes.
post.no_of_likes = Like.objects.filter(post=post).count()
post.save()
return JsonResponse({"message": "successfully liked", "no_of_likes": post.no_of_likes})
@login_required
def unlike(request, post_id):
post = Post.objects.get(pk=post_id)
user = User.objects.get(pk=request.user.id)
like = Like.objects.filter(user=user, post=post)
like.delete()
# Update no of likes.
post.no_of_likes = Like.objects.filter(post=post).count()
post.save()
return JsonResponse({"message": "successfully unliked", "no_of_likes": post.no_of_likes})
index.html 与 Javascript
{% if post.id not in liked_posts %}
<button type="button" class="btn btn-primary" id="like{{ post.id }}" onclick="like('{{ post.id }}')">Like</button>
{% else %}
<button type="button" class="btn btn-primary" id="unlike{{ post.id }}"onclick="unlike('{{ post.id }}')">Unlike</button>
{% endif %}
function like(id) {
fetch(`/like/${id}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": "{{ csrf_token }}",
},
})
.then(response => response.json())
.then(data => {
document.querySelector(".no-of-likes").innerHTML = data.no_of_likes + " likes";
})
.then(() => {
document.getElementById("unlike" + id).style.display = "block";
document.getElementById("like" + id).style.display = "none";
});
}
function unlike(id) {
fetch(`/unlike/${id}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": "{{ csrf_token }}",
},
})
.then(response => response.json())
.then(data => {
document.querySelector(".no-of-likes").innerHTML = data.no_of_likes + " likes";
})
.then(() => {
document.getElementById("unlike" + id).style.display = "none";
document.getElementById("like" + id).style.display = "block";
});
}
我可以在不刷新页面的情况下更新计数器,但这与按钮不同。 这就是发生的事情:
--> 当我单击 Like 按钮时计数器更新。我必须刷新页面才能将按钮更改为“不同”。根据规范,这需要异步完成(假设在 Javascript 的帮助下!),无需重新加载页面。
--> 与“不同”按钮也相同。当我单击它时,计数器会更新,但我必须重新加载页面才能将按钮更改为“喜欢”。
我想更改按钮而不重新加载页面。尝试将代码块放置在不同的位置,尝试使用“if else”条件,但我仍然卡在这里。任何帮助表示赞赏! 抱歉,这里的 Javascript 代码很乱,新手。
那是因为您只渲染了一个按钮。添加两个,一个隐藏,另一个显示:
但我不明白为什么你需要首先使用两个按钮:只需使用一个按钮,根据上下文即可用于喜欢和不喜欢。
注意:请不要在模型中存储聚合:在需要时确定聚合:在模型中存储聚合会使更新和保持数据同步变得更加困难。您可以在需要时使用
[Django-doc] 为每个对象生成计数、总和等。.annotate(…)