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样式就行了。
posted on 2018-07-14 08:14 yujie158392613 阅读(831) 评论(0) 编辑 收藏 举报