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')

posted @ 2020-06-12 22:28  the3times  阅读(229)  评论(0编辑  收藏  举报