【一】前端基本页面
<div class="media">
<div>
<div class="media-heading pull-right">
随笔 - {{ article_data_obj.count }} 点赞数 - {{ article_obj.up_num }} 点踩数
- {{ article_obj.down_num }}
评论数 - {{ article_obj.comment_num }}
</div>
<br>
<div class="media-title">
<h4> {{ article_obj.title }}</h4>
</div>
<hr>
<div class="media-body">
{# 看到页面上的效果是页面源码 带标签的页面源码 而不是 页面 #}
{# 两种解决办法 : 一种是在前端加转换器 |safe 另一种是在后端你直接对源代码 进行 mark_safe #}
{{ article_obj.content|safe }}
</div>
<div class="pull-right">
<div class="media-bottom">
{# 去copy别人写好的点赞点踩样式#}
<div class="diggit" onclick="votePost({{ article_obj.pk }},'Digg')">
<span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
</div>
<div class="buryit" onclick="votePost({{ article_obj.pk }},'Bury')">
<span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
</div>
</div>
【二】后端逻辑
- 点击点赞之后可以点赞+1
- 点击点踩之后可以取消点踩
def up_down(request, *args, **kwargs):
# 先校验当前用户是否登录,如果没有登陆则让其先登录
if not request.user.is_authenticated:
return CommonReponse(code=2001, errors=mark_safe("请先<a href='/user/login/'>登录</a> 后再发表评论!"))
# 处理点赞或者点踩的逻辑
data = request.POST
article_id = data.get("article_id")
up_or_down = json.loads(data.get("up_or_down")) # 字符串形式的 false / true
# 获取到当前用户对象和文章对象
user_obj = request.user
article_obj = Article.objects.get(pk=int(article_id))
# 校验当前用户是否是文章的作者,如果是当前文章的作者则不允许给自己点赞或点踩
if user_obj.username == article_obj.blog.userinfo.username:
return CommonReponse(code=2005, errors=f"不能给自己点赞或点踩!")
# 调用点赞或者点踩表进行点赞或者点踩数据的写入
# 【1】先确认当前用户是否给当前文章点赞或者点踩过
try:
# 使用get方法获取用户对象的时候不存在会报错
up_down_obj = UpAndDown.objects.get(user=user_obj, article=article_obj)
# 【2】如果当前用户没有给当前文章点赞或点踩过则新增点赞点踩信息
except Exception:
UpAndDown.objects.create(user=user_obj, article=article_obj, up_or_down=up_or_down)
if up_or_down:
article_obj.up_num += 1
article_obj.save()
return CommonReponse(code=2000, message="点赞成功!")
else:
article_obj.down_num += 1
article_obj.save()
return CommonReponse(code=2000, message="点踩成功!")
# 【3】如果已经存在点赞点踩记录
# (1)如果当前是点赞的状态并且发送的数据页是点赞
if up_down_obj.up_or_down and up_or_down:
return CommonReponse(code=2002, errors="当前用户已经点赞过了!")
# (3)当前状态是点踩并且发送的也是点踩
elif not up_down_obj.up_or_down and not up_or_down:
return CommonReponse(code=2002, errors="当前用户已经点踩过了!")
# (2)如果当前是点赞的状态并且发送的数据页是点踩
elif up_down_obj.up_or_down and not up_or_down:
# 将当前点赞的信息重置为点踩
up_down_obj.up_or_down = up_or_down
article_obj.up_num -= 1
article_obj.down_num += 1
up_down_obj.save()
article_obj.save()
return CommonReponse(code=2000, message=f"当前点踩成功,感谢指教!")
else:
# 将当前点赞的信息重置为点赞
up_down_obj.up_or_down = up_or_down
article_obj.up_num += 1
article_obj.down_num -= 1
up_down_obj.save()
article_obj.save()
return CommonReponse(code=2000, message=f"当前点赞成功,感谢支持!")
【三】前端逻辑
<div class="clearfix">
<div class="pull-right">
<div class="media-bottom">
{# 去copy别人写好的点赞点踩样式#}
<div class="diggit" onclick="votePost({{ article_obj.pk }},'Digg')">
<span class="diggnum" id="digg_count">{{ article_obj.up_num }}</span>
</div>
<div class="buryit" onclick="votePost({{ article_obj.pk }},'Bury')">
<span class="burynum" id="bury_count">{{ article_obj.down_num }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function votePost(article_id, tag) {
let numEle="#"+tag.toLowerCase() +"_count"
let tipEle = $("#digg_tips");
{#区分tag是点赞还是点踩#}
let data = {
'article_id': article_id,
{#三元表达式#}
'up_or_down': 1 ? tag === "Digg" : 0,
"csrfmiddlewaretoken": "{{ csrf_token }}",
}
$.ajax({
{#因为向某一个路由地址发解析#}
url: '{% url 'up_down' %}',
type: 'POST',
data: data,
success: (response) => {
if (response.code === 2000) {
{#让当前点赞数或者点踩数+1#}
$(numEle).text(parseInt($(numEle).text())+1)
tipEle.text(response.message)
} else {
tipEle.text(response.errors)
$(numEle).text(parseInt($(numEle).text())-1)
}
}
}
)
}
<script>