DAY15 用户评论点赞的实现
表分析
点赞是用户和评论之间发生的事情,并且直接存在着多对多的关系,当点赞发生后会往后台存入数据来记录,也就是需要单独的一张点赞表来进行
记录,点赞表的字段记录用户表的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给前台就行。

浙公网安备 33010602011771号