如何在 Django 博客中添加“点赞/取消点赞”按钮
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
在本迷你教程中,我们将为 Django 博客添加点赞/取消点赞功能。需要注意的是,我们将使用基于类的视图来实现博客文章详情视图 (DetailView) 的此功能。
第二点说明:遗憾的是,我们无法避免每次点击“点赞/取消点赞”按钮后页面都会刷新。为了避免页面刷新,需要使用 Ajax.js 在博客文章详情页的 HTML 代码中实现“点赞/取消点赞”按钮的全部功能。本教程不会重点介绍这种实现方式。
首先,models.py我们需要在 BlogPost 模型中添加以下字段:
# models.py
from django.db import models
from django.contrib.auth.models import User
class BlogPost(models.Model):
...
likes = models.ManyToManyField(User, related_name='blogpost_like')
def number_of_likes(self):
return self.likes.count()
“likes”与我们的用户模型之间存在多对多关系,这意味着用户(对象)可以有多个点赞,博客文章也可以有多个点赞。函数`number_of_likes`将返回当前博客文章对象的点赞数。
每次修改 models.py 文件后,我们需要打开终端并执行数据库迁移:
# CLI/Terminal
>> cd C:\Projects\...\YourDjangoAppMainFolder
>> python manage.py makemigrations
>> python manage.py migrate
现在我们来为“点赞”按钮功能创建一个基于函数的视图。在你的view.py文件中,在 BlogPost DetailView 类之前(或之后),定义一个 BlogPostLike 函数:
# views.py
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
def BlogPostLike(request, pk):
post = get_object_or_404(BlogPost, id=request.POST.get('blogpost_id'))
if post.likes.filter(id=request.user.id).exists():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return HttpResponseRedirect(reverse('blogpost-detail', args=[str(pk)]))
'blogpost_id'将作为我们按钮的标识符blogpost_detail.html。每次登录用户点击“点赞”按钮时,我们会获取该用户的 ID,然后检查该用户是否已经点赞过当前博文(更具体地说:如果用户 x 已经点赞过,则从当前博文中移除该点赞;否则,将用户 x 的点赞添加到当前博文)。之后,我们会将用户重定向到同一篇博文的页面(相当于刷新该页面)。
现在,在我们已经实现 BlogPost DetailView 的同一个view.py文件中,我们需要在 get_context_data 中添加以下内容:
# views.py
class BlogPostDetailView(DetailView):
model = BlogPost
# template_name = MainApp/BlogPost_detail.html
# context_object_name = 'object'
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
likes_connected = get_object_or_404(BlogPost, id=self.kwargs['pk'])
liked = False
if likes_connected.likes.filter(id=self.request.user.id).exists():
liked = True
data['number_of_likes'] = likes_connected.number_of_likes()
data['post_is_liked'] = liked
return data
在我们的get_context_data函数中,我们将获取当前博客文章的主键,并检查当前登录用户是否点赞了该博客文章。我们将此结果存储在一个局部变量中,以便将其作为上下文传递给基于 HTML 的 blogpost_detail 组件。我们还将获取点赞数(调用之前编写的函数),以便直接在 HTML 模板中显示点赞数。
让我们也把这个新的基于函数的视图添加到我们的urls.py:
# urls.py
from django.urls import path
from .views import (
...
BlogPostLike,
...
)
urlpatterns = [
...
path('blogpost-like/<int:pk>', views.BlogPostLike, name="blogpost_like"),
...
]
最后,让我们blogpost_detail.html用 DjangoTemplateLanguage 编写以下内容:
<!-- LIKES -->
{% if user.is_authenticated %}
<form action="{% url 'blogpost_like' object.id %}" method="POST">
{% csrf_token %}
{% if post_is_liked %}
<button type="submit" name="blogpost_id" value="{{object.id}}" class="btn btn-info">Unlike</button>
{% else %}
<button type="submit" name="blogpost_id" value="{{object.id}}" class="btn btn-info">Like</button>
{% endif %}
</form>
{% else %}
<a class="btn btn-outline-info" href="{% url 'login' %}?next={{request.path}}">Log in to like this article!</a><br>
{% endif %}
<strong class="text-secondary">{{ number_of_likes }} Like{{ number_of_likes|pluralize }}</strong>
我们完成了!
文章来源:https://dev.to/radualexandrub/how-to-add-like-unlike-button-to-your-django-blog-5gkg