BBS项目文章点赞功能
文章点赞点踩技术点分析总结
前端
- 点赞图片和点踩图片被点击时触发点击事件,朝后端发送点赞或者点踩请求
- 点击事件内发送ajax请求,朝后端发送数据:当前文章主键值、布尔值(判断点赞还是点踩)
- 等待接收后端传过来的响应信息,如果不符合条件则显示提示信息;如果可以则通过DOM操作更新页面的点赞数或点踩数(注意数字和字符串类型的转化)。
后端
-
后端判断请求为aja提交的post请求后,接收文章主键值和布尔值数据(布尔值需要反序列化)
-
逻辑判断:
-
用户是否登录,登录后才能点赞或点踩(request.user.is_authenticated)
-
如果登陆,该文章是否是自己的文章,不能给自己的文章点赞或点踩(models.Article表)
-
如果不是自己的,那么判断是否已经给该文章点过赞或踩(models.UpDown表)
-
如果没有点过,则符合条件允许操作;此时需要同时更新文章表和点赞表,使用事物的原子性(数据同步更新)。此时需要用到ORM的
F
查询方便数据的更新。 -
上述有一个判断不满足则不能点赞操作,需要给前端返回不同的自定义状态码和提示信息。
-
上述所有的判断都需要用到ORM表查询判断。
-
代码
前端
{# 点赞点踩区start#}
<div class="clearfix">
<div id="div_digg">
<div class="diggit my_flag">
<span class="diggnum" id="digg_count">{{ article_obj.up_counts }}</span>
</div>
<div class="buryit my_flag">
<span class="burynum" id="bury_count">{{ article_obj.down_counts }}</span>
</div>
<div class="clear"></div>
<div class="diggword" id="digg_tips">
</div>
<span style="color: red" id="diggit_info"></span>
</div>
</div>
{# 点赞点踩区end#}
{#点赞js#}
<script>
$('.my_flag').click(function () {
let isUpDiv = $(this);
let isUp = isUpDiv.hasClass('diggit');
$.ajax({
url: '{% url "up_and_down" %}',
type: 'post',
data:{
'article_id': {{ article_id }},
'is_up': isUp
},
success: function (args) {
if (args.code === 1000){
$('#diggit_info').text(args.msg);
let oldCount = isUpDiv.children().text();
isUpDiv.children().text(Number(oldCount) + 1);
}else{
$('#diggit_info').html(args.msg)
}
}
})
});
</script>
后端视图函数
def up_and_down(request):
if request.is_ajax() and request.method == 'POST':
back_info = {'code': 1000}
article_id = request.POST.get('article_id')
is_up = json.loads(request.POST.get('is_up')) # 反序列化成布尔型
print(article_id, is_up)
# 判断当前用户是否登录
if request.user.is_authenticated:
# 判断当前用户是否点赞自己的文章
if not models.Article.objects.filter(pk=article_id, blog__userinfo=request.user):
# 判断用户是否已经给这篇文章点过赞了
if not models.UpDown.objects.filter(user=request.user, article__pk=article_id):
with transaction.atomic():
if is_up:
models.Article.objects.filter(pk=article_id).update(up_counts=F('up_counts')+1)
else:
models.Article.objects.filter(pk=article_id).update(down_counts=F('down_counts')+1)
models.UpDown.objects.create(user=request.user, article_id=article_id, is_up=is_up)
back_info['msg'] = '成功点赞' if is_up else '成功点踩'
else:
action = models.UpDown.objects.filter(user=request.user, article__pk=article_id).first().is_up
back_info['code'] = 1002
back_info['msg'] = '您已经点赞了' if action else '您已经点踩了'
else:
back_info['code'] = 1003
back_info['msg'] = '不能给自己点赞哦'
else:
back_info['code'] = 1004
back_info['msg'] = '不<a href="/login/">登录</a>不让点'
return JsonResponse(back_info)
else:
return render(request, 'error404.html')