zoukankan      html  css  js  c++  java
  • 2018.7.13-点赞踩和多级评论功能总结

    点赞功能的实现

     首先在文章内容下写出两个div标签,并绑定点击事件,此事件函数需要传入的参数有本标签对象、文章id、判断赞还是踩的参数:

       <div>
            <span onclick="up_down_click(this, {{ select_article.nid }}, 1);">赞</span>
            <i id="up_screen">{{ select_article.up_count }}</i>
        </div>
        <div>
            <span onclick="up_down_click(this, {{ select_article.nid }}, 0);">踩</span>
            <i id="down_screen">{{ select_article.down_count }}</i>
        </div>
    

    利用jq写好将相关参数传到后台的逻辑,注意csrf_token的获取:

    function up_down_click(ths, article_id, val) {
            $.ajax({
                url: '/up_down_click/',
                data: {'val': val, 'article_id': article_id, 'csrfmiddlewaretoken': '{{csrf_token}}', },
                type: 'POST',
                dataType: 'JSON',
                success:function (arg) {
                    //接收服务器处理后的数据要做的事
                }
            })
        }
    

    配置好路由:

    path('up_down_click/', views.up_down_click),  # 点赞踩功能
    

    然后就是写up_down_click()函数的问题了,写此函数的时候需要注意几点,1.想好传送到后台的数据结构。2.由于赞踩在数据库中分有两个表,所以要绑定事务操作。具体写法如下:

    def up_down_click(request):
        """
        赞踩处理
        :param request:
        :return:
        """
        response = {'code': 1000, 'msg': None}  # 发送至前台的处理信息。1001代表赞,1002代表踩,1000代表有错误
        try:
            user_id = request.session.get('user_id')
            v = int(request.POST.get('val'))  # 接收赞踩参数,1为赞 0为踩
            article_id = request.POST.get('article_id')
            obj = models.UpDown.objects.filter(user_id=user_id, article_id=article_id).first()  # 查询是否已经点过赞或者踩过
            if obj:  # 如果赞踩过
                response['msg'] = '已经赞踩过'
                print('已经赞踩过')
            else:  # 如果没有赞踩过
                with transaction.atomic():  # 事务操作,绑定两次数据库操作
                    if v:  # 赞记录收录
                        models.UpDown.objects.create(user_id=user_id, article_id=article_id, up=True)
                        models.Article.objects.filter(nid=article_id).update(up_count=F('up_count') + 1)
                        response['code'] = 1001
                    else:  # 踩记录收录
                        models.UpDown.objects.create(user_id=user_id, article_id=article_id, up=True)
                        models.Article.objects.filter(nid=article_id).update(down_count=F('down_count') + 1)
                        response['code'] = 1002
        except Exception as e:
            response['msg'] = str(e)  # 错误信息存入msg字段
        print(json.dumps(response))
        return HttpResponse(json.dumps(response))
    

      最后就是前台jq对数据的处理,利用.text()和Number()函数可以将对应标签内的个数自增,完整处理代码如下:

    function up_down_click(ths, article_id, val) {
            $.ajax({
                url: '/up_down_click/',
                data: {'val': val, 'article_id': article_id, 'csrfmiddlewaretoken': '{{csrf_token}}', },
                type: 'POST',
                dataType: 'JSON',
                success:function (arg) {
                    var num_up = $("#up_screen");
                    var num_down = $("#down_screen");
                    if(arg.code == '1001'){
                        num_up.text(Number(num_up.text())+1);
                    }else if(arg.code == '1002'){
                        num_down.text(Number(num_down.text())+1);
                    }else{
                        //显示错误信息
                    }
                }
            })
        }
    

    多级评论功能的实现

    首先是对数据库数据的处理,对于这个相应的算法我在这篇博客中已经详细分析过,这里贴上代码:

    def get_talk_list(request):
        """
        处理评论列表数据
        :param request: 
        :return: 
        """
        article_id = request.POST.get('article_id')
        # 获取评论
        talk_list = models.Comment.objects.filter(article_id=article_id).values('nid', 'user__username', 'content',
                                                                                'reply_id')
        """
        处理评论数据
        """
        msg_2_list = {}
        for i in talk_list:
            i['child'] = []
            msg_2_list[i['nid']] = i
        result = []
        for item in talk_list:
            if item['reply_id']:
                msg_2_list[item['reply_id']]['child'].append(item)
            else:
                result.append(item)
        # print(json.dumps(result))
        return HttpResponse(json.dumps(result))
    

      最重要的还是利用处理后的数据将对应多级评论显示在页面上,想了想算法,估计会用到递归,如果将这些逻辑写到服务器上势必会消耗大量服务器资源,所以利用js写在页面上是最好的选择,对于js不是太熟练的我只好硬着头皮上了:D。

    再写算法之前,第一个要处理的事情就是怎么接受服务器处理好的数据,在页面框架加载完成后利用ajax接收数据我觉得是个不错的选择:

    $(function () {
            $.ajax({
                url: '/talk_list/',
                data: {'article_id': {{ select_article.nid }}, 'csrfmiddlewaretoken': '{{csrf_token}}', },
                type: 'POST',
                dataType: 'JSON',
                success:function (args) {
                    console.log(args);
                }
            });
        });
    

    下面就是递归算法,利用字符串拼接的想法,将所有评论用对应div包裹,返回最后的结果,其中注意js对于JSON数据的处理方法:

        function talk_screen(obj) {
            let comment_str = "<div class='comment'>";
            $.each(obj, function (n, value) {
                let tpl = "<div class='content'>"+value.content+"</div>";   // 每一条评论数据用div包裹
                //console.log(value.content);
                comment_str += tpl;
                console.log(comment_str);
                if (value.child != ''){     // 递归边界
                    //console.log(value.child);
                    let child_str = talk_screen(value.child);
                    comment_str += child_str;
                }
            });
            comment_str += "</div>";        // 封口
            return comment_str;
        }
    

    最后利用.html()方法将数据放入对于div中显示出来:

    $('#talk_list').html(talk_screen(args));
    

    最后加上一些css样式就行了。

  • 相关阅读:
    cmd设置代理
    移动端坐标定位tap
    T02-Django基本应用结构
    支持向量机算法的Sklearn完整复现
    T01-何为Django,入门"Hello World"
    决策树算法的Sklearn完整复现
    逻辑回归算法的Sklearn完整复现
    线性回归算法Sklearn完整复现
    K-近邻算法的Sklearn完整复现
    数据分析中的'疑难杂症'小结(三)
  • 原文地址:https://www.cnblogs.com/yu-jie/p/9308385.html
Copyright © 2011-2022 走看看