表分析
点赞是用户和评论之间发生的事情,并且直接存在着多对多的关系,当点赞发生后会往后台存入数据来记录,也就是需要单独的一张点赞表来进行
记录,点赞表的字段记录用户表的ID和评论表的ID来维持多对多关系。
表结构分析完后就该处理端口了
点赞端口
因为我们需要用到局部刷新,也就是在用户点赞后不刷新页面进行点赞的显示和点赞数的增加,
所以我们的端口规范和之前的评论端口差不多,也就是json格式,post请求格式,返回json。
接收的参数我们只需要评论的ID以及用户进行的行为(action),也就是进行的点赞还是取消点赞
新闻的ID的话,点赞只存在新闻页面里面,所以可以不用判断新闻是否存在
确认参数后就可以进行后台代码的编写了
后台代码
首先还是创建新的视图函数并在文档注释里写入实现功能,记得设置请求方式
完成之后整理思路,在注释里写下思路:
第一步
# 1. 获取用户登录状态 user = g.user if not user: return jsonify(errno=RET.SESSIONERR,errmsg="用户未登录")
点赞是只有当用户登录了之后才能进行
第二步
# 2. 接收参数(comment_id,action(add,remove),news_id) comment_id = request.json.get("comment_id") action = request.json.get("action")
接收json格式的数据
第三步
# 3. 校验参数 # 3.1 校验参数是否齐全 if not all([comment_id,action]): return jsonify(errno=RET.PARAMERR,errmsg="参数缺失") # 3.2 判断comment_id,news_id是否为整形 try: comment_id = int(comment_id) except Exception as e : current_app.logger.error(e) return jsonify(errno=RET.PARAMERR,errmsg="非法参数") # 3.3 判断action的值是否合法 if action not in ["add","remove"]: return jsonify(errno=RET.PARAMERR,errmsg="非法参数") # 3.4 校验评论是否存在 try: comment = Comment.query.get(comment_id) except Exception as e : current_app.logger.error(e) return jsonify(errno=RET.DBERR,errmsg="数据读取失败") if not comment : return jsonify(errno=RET.NODATA, errmsg="评论未找到")
对接收的参数进行校验,参数是否齐全,参数的数据类型是否正确,参数是否合法,并通过评论的ID查询评论是否存在。查询放在最后
第四步
# 4.通过action的值来进行不同的操作 try: commentLike = CommentLike.query.filter_by(user_id=user.id,comment_id=comment.id).first() except Exception as e: current_app.logger.error(e) return jsonify(errno=RET.DBERR, errmsg="数据库连接失败") if action == "add": if not commentLike: new_commentLike =CommentLike() new_commentLike.comment_id = comment.id new_commentLike.user_id = user.id comment.like_count += 1 #对应评论的点赞数 try: db.session.add(new_commentLike) db.session.commit() except Exception as e : current_app.logger.error(e) db.session.rollback() return jsonify(errno=RET.DBERR,errmsg="保存失败") else: if commentLike: try: db.session.delete(commentLike) comment.like_count -= 1 db.session.commit() except Exception as e : current_app.logger.error(e) db.session.rollback() return jsonify(errno=RET.DBERR,errmsg="删除失败")
首先需要对点赞表中的记录进行查询,然后再通过action的值以及对数据的判断来进行操作,当值为add且不存在数据时添加数据,当值为remove
且值存在时进行删除,另外还需要对该条评论的点赞数字段进行对应的处理,对数据进行操作所以需要回滚
第五步
# 5.返回结果 return jsonify(errno=RET.OK,errmsg="成功")
返回json,回调函数根据值进行不同的执行。
前台代码:
js代码:
// TODO : 点赞 if(sHandler.indexOf('comment_up')>=0) { var $this = $(this); var action = "add"; if(sHandler.indexOf('has_comment_up')>=0) { // 如果当前该评论已经是点赞状态,再次点击会进行到此代码块内,代表要取消点赞 action = "remove" } var comment_id = $(this).attr("data-commentid") var news_id = $(this).attr("data-newsid") var params = { "comment_id": comment_id, "action": action, "news_id": news_id } $.ajax({ url: "/news/comment_like", type: "post", contentType: "application/json", headers: { "X-CSRFToken": getCookie("csrf_token") }, data: JSON.stringify(params), success: function (resp) { if (resp.errno == "0") { var like_count = $this.attr('data-likecount') if (like_count == undefined) { like_count = 0 } // 更新点赞按钮图标 if (action == "add") { like_count = parseInt(like_count) + 1 // 代表是点赞 $this.addClass('has_comment_up') }else { like_count = parseInt(like_count) - 1 $this.removeClass('has_comment_up') } // 更新点赞数据 $this.attr('data-likecount', like_count) if (like_count == 0) { $this.html("赞") }else { $this.html(like_count) } }else if (resp.errno == "4101"){ $('.login_form_con').show(); }else { alert(resp.errmsg) } } }) }
HTML代码
<a href="javascript:;" class="comment_up {% if comment.is_like %} has_comment_up {% endif %} fr" data-commentid="{{ comment.id }}" data-likecount="{{ comment.like_count }}" data-newsid="{{ news.id }}"> {% if comment.like_count > 0 %} {{ comment.like_count }} {% else %} 赞 {% endif %} </a>
前端显示
完成之后,我们还需要对前端的点赞图标显示进行相关处理,当用户点赞后点赞图标应该是一直高亮的状态,也就是用户下个动作
只能是取消
这是关于我们的详情页显示,所以我们在渲染详情页的视图函数中进行修改,前端已经设定好了判断条件,我们只需将值
从后台传过去就行。
后台代码:
# 6.点赞相关展示 new_comments = [] for comment in comments: if user: if comment in user.collection_comment: comment = comment.to_dict() comment["is_like"] = True else: comment = comment.to_dict() comment["is_like"] = False else: comment = comment.to_dict() new_comments.append(comment)
我们需要对传入前端评论的上下文进行再构造,并在评论类的转字典函数里添加我们的判断条件"is_like",
只有当用户点赞了这条评论我们才添加,还有只有当用户登录时才能进行相关的判断代码的执行,不然会
报错,我上面是通过在user的模型类里添加了查询字段来进行的用户点赞评论的判断,
也就是通过第三张表进行评论表的相关操作
还可以通过查询来进行,也就是在评论表找到符合该用户id的所有数据,并通过查询到的数据获取到评论的ID,然后再进行判断评论的ID是否在里面来进行
但是所有的操作都要注意到用户的登录状态,因为都需要用到用户的数据来进行,所以都需要先对用户登录状态进行判断后再进行
最后将我们构造好的new_comments给前台就行。