发布评论的问题

发布评论的问题

问题描述:

不能成功发布评论,也没有 alert 的弹窗提示

相关代码:

views.py
from flask import Blueprint, render_template, request, abort, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user

from models import Question, Answer, AnswerComment, db
from qa.forms import WriteQuestionForm, WriteAnswerForm

qa = Blueprint('qa', __name__,
template_folder='templates',
static_folder='../assets')


@qa.route('/')
def index():
""" 首页 回答列表 """
per_page = 20 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Answer.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('index.html', page_data=page_data)


@qa.route('/follow')
def follow():
""" 关注 问题列表 """
per_page = 20 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('follow.html', page_data=page_data)


@qa.route('/qa/list')
def question_list():
""" 查询问题数据列表
// json
{
'code': 0,
'data': ''
}
"""
try:
per_page = 2 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
data = render_template('qa_list.html', page_data=page_data)
return {'code': 0, 'data': data}
except Exception as e:
print(e)
data = ''
return {'code': 1, 'data': ''}


@qa.route('/write', methods=['GET', 'POST'])
@login_required
def write():
""" 写文章,提问 """
form = WriteQuestionForm()
if form.validate_on_submit():
try:
que_obj = form.save()
if que_obj:
flash('发布问题成功', 'success')
return redirect(url_for('qa.index'))
except Exception as e:
print(e)
flash('发布问题失败,请稍后重试', 'danger')
return render_template('write.html', form=form)


@qa.route('/detail/<int:q_id>', methods=['GET', 'POST'])
def detail(q_id):
""" 问题详情 """
# 1. 查询问题信息
question = Question.query.get(q_id)
if not question.is_valid:
abort(404)
# 2. 展示第一条回答信息
answer = question.answer_list.filter_by(is_valid=True).first()
# 添加回答
form = WriteAnswerForm()
if form.validate_on_submit():
try:
if not current_user.is_authenticated:
flash('请先登录', 'danger')
return redirect(url_for('accounts.login'))
form.save(question=question)
flash('回答问题成功', 'success')
return redirect(url_for('qa.detail', q_id=q_id))
except Exception as e:
print(e)
return render_template('detail.html',
question=question,
answer=answer,
form=form)


@qa.route('/comments/<int:answer_id>', methods=['GET', 'POST'])
def comments(answer_id):
""" 评论 """
answer = Answer.query.get(answer_id)
if request.method == 'POST':
# 添加评论
try:
if not current_user.is_authenticated:
result = {'code': 1, 'message': '请登录'}
return jsonify(result), 400
# 1. 获取数据
content = request.form.get('content', '')
reply_id = request.form.get('reply_id', None)
# 2. 保存到数据库
question = answer.question
comment_obj = AnswerComment(content=content,
user=current_user,
answer=answer,
reply_id=reply_id,
question=question
)
db.session.add(comment_obj)
db.session.commit()
return '', 201
except Exception as e:
result = {'code': 1, 'message': '服务器正忙,请稍后重试'}
return jsonify(result), 400
else:
# 获取评论列表
try:
page = int(request.args.get('page', 1))
page_data = answer.comment_list().paginate(page=page, per_page=1)
data = render_template('comments.html', page_data=page_data, answer=answer)
return jsonify({'code': 0, 'data': data, 'meta': {'page': page}}), 200
except Exception as e:
print(e)
return jsonify({'code': 1, 'data': '', 'message': '服务器正忙'}), 500


@qa.route('/comment/love/<int:comment_id>', methods=['POST'])
# @login_required
def comment_love(comment_id):
""" 为评论点赞 """
try:
if not current_user.is_authenticated:
return '', 401
comment_obj = AnswerComment.query.get(comment_id)
comment_obj.love_count += 1
db.session.add(comment_obj)
db.session.commit()
except Exception as e:
print(e)
abort(500)
return '', 201
from flask import Blueprint, render_template, request, abort, redirect, url_for, flash, jsonify
from flask_login import login_required, current_user

from models import Question, Answer, AnswerComment, db
from qa.forms import WriteQuestionForm, WriteAnswerForm

qa = Blueprint('qa', __name__,
template_folder='templates',
static_folder='../assets')


@qa.route('/')
def index():
""" 首页 回答列表 """
per_page = 20 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Answer.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('index.html', page_data=page_data)


@qa.route('/follow')
def follow():
""" 关注 问题列表 """
per_page = 20 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
return render_template('follow.html', page_data=page_data)


@qa.route('/qa/list')
def question_list():
""" 查询问题数据列表
// json
{
'code': 0,
'data': ''
}
"""
try:
per_page = 2 # 每页数据的大小
page = int(request.args.get('page', 1))
page_data = Question.query.filter_by(is_valid=True).paginate(
page=page, per_page=per_page)
data = render_template('qa_list.html', page_data=page_data)
return {'code': 0, 'data': data}
except Exception as e:
print(e)
data = ''
return {'code': 1, 'data': ''}


@qa.route('/write', methods=['GET', 'POST'])
@login_required
def write():
""" 写文章,提问 """
form = WriteQuestionForm()
if form.validate_on_submit():
try:
que_obj = form.save()
if que_obj:
flash('发布问题成功', 'success')
return redirect(url_for('qa.index'))
except Exception as e:
print(e)
flash('发布问题失败,请稍后重试', 'danger')
return render_template('write.html', form=form)


@qa.route('/detail/<int:q_id>', methods=['GET', 'POST'])
def detail(q_id):
""" 问题详情 """
# 1. 查询问题信息
question = Question.query.get(q_id)
if not question.is_valid:
abort(404)
# 2. 展示第一条回答信息
answer = question.answer_list.filter_by(is_valid=True).first()
# 添加回答
form = WriteAnswerForm()
if form.validate_on_submit():
try:
if not current_user.is_authenticated:
flash('请先登录', 'danger')
return redirect(url_for('accounts.login'))
form.save(question=question)
flash('回答问题成功', 'success')
return redirect(url_for('qa.detail', q_id=q_id))
except Exception as e:
print(e)
return render_template('detail.html',
question=question,
answer=answer,
form=form)


@qa.route('/comments/<int:answer_id>', methods=['GET', 'POST'])
def comments(answer_id):
""" 评论 """
answer = Answer.query.get(answer_id)
if request.method == 'POST':
# 添加评论
try:
if not current_user.is_authenticated:
result = {'code': 1, 'message': '请登录'}
return jsonify(result), 400
# 1. 获取数据
content = request.form.get('content', '')
reply_id = request.form.get('reply_id', None)
# 2. 保存到数据库
question = answer.question
comment_obj = AnswerComment(content=content,
user=current_user,
answer=answer,
reply_id=reply_id,
question=question
)
db.session.add(comment_obj)
db.session.commit()
return '', 201
except Exception as e:
result = {'code': 1, 'message': '服务器正忙,请稍后重试'}
return jsonify(result), 400
else:
# 获取评论列表
try:
page = int(request.args.get('page', 1))
page_data = answer.comment_list().paginate(page=page, per_page=1)
data = render_template('comments.html', page_data=page_data, answer=answer)
return jsonify({'code': 0, 'data': data, 'meta': {'page': page}}), 200
except Exception as e:
print(e)
return jsonify({'code': 1, 'data': '', 'message': '服务器正忙'}), 500


@qa.route('/comment/love/<int:comment_id>', methods=['POST'])
# @login_required
def comment_love(comment_id):
""" 为评论点赞 """
try:
if not current_user.is_authenticated:
return '', 401
comment_obj = AnswerComment.query.get(comment_id)
comment_obj.love_count += 1
db.session.add(comment_obj)
db.session.commit()
except Exception as e:
print(e)
abort(500)
return '', 201

detail.html
{% extends 'base_layout.html' %}
{% from 'macro/answer_comment_item.html' import comment_item_show %}
{% block title %}{{ super() }} - 文章详情{% endblock %}
{% block header %}
<link rel="stylesheet" href="/assets/style/detail.css">
{% endblock %}
{% block content %}
<!-- 问题简述 -->
<div class="layout-question">
<div class="container">
<div class="row">
<div class="col-md-9">
{% include 'components/flash_messages.html' %}
<!-- 问题标签 -->
{% if question.tags %}
<ul class="que-tag-ls">
{% for tag in question.tags %}
<li><a href="#">{{ tag.tag_name }}</a></li>
{% endfor %}
</ul>
{% endif %}
<!-- // 问题标签 -->
<h3>{{ question.title }}</h3>
<div class="show-desc hidden">
{{ question.desc|d('暂无', True) }}…
<span class="btn-show-more">显示全部<i class="glyphicon glyphicon-menu-down"></i></span>
</div>
<div class="show-all ">
{% autoescape false %}
{{ question.content|safe }}
{% endautoescape %}
<span class="btn-show-less">收起<i class="glyphicon glyphicon-menu-up"></i></span>
</div>
<!-- 菜单栏 -->
<div class="qa-footer">
<div>
<button type="button" class="btn btn-info btn-sm">关 注</button>
</div>
<div>
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#addComment">
写回答
</button>
</div>
<div class="txt-menu"><i class="glyphicon glyphicon-comment"></i> {{ question.comment_count }}条评论
</div>
<div class="txt-menu"><i class="glyphicon glyphicon-send"></i>分享</div>
<div class="txt-menu"><i class="glyphicon glyphicon-flag"></i>举报</div>
<div class="txt-menu"></div>
<div class="txt-menu btn-group">
<i class="glyphicon glyphicon-option-horizontal dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"></i>
<ul class="dropdown-menu">
<li><a href="#">不感兴趣</a></li>
</ul>
</div>
</div>
<!-- //菜单栏 -->
</div>
<div class="col-md-3">
<div class="que-stats-box">
<!-- 关注者 -->
<div>
<span>关注者</span>
<strong>{{ question.follow_count|number_split }}</strong>
</div>
<!-- //关注者 -->
<!-- 被浏览 -->
<div>
<span>被浏览</span>
<strong>{{ question.view_count|number_split }}</strong>
</div>
<!-- //被浏览 -->
</div>
</div>
</div><!-- // row -->
</div>
</div>
<!-- // 问题简述 -->

<div class="layout-answer">
<div class="container">
<div class="row">
<div class="col-md-9 left-content">
{% block link_more %}
<a class="link-more" href="#">查看全部 {{ question.answer_count|number_split }} 个回答</a>
{% endblock %}
<!-- 回答内容区域 -->
{% if answer %}
<div class="answer-content box-wrap">
<div class="user-info">
<div class="avater">
{% if answer.user.avatar %}
<img src="{{ answer.user.avatar }}" alt="用户头像">
{% else %}
<img src="/assets/home/qa/user_head.jpg" alt="用户头像">
{% endif %}
</div>
<div class="desc">
<h4>{{ answer.user.nickname }}</h4>
<p>{{ answer.user.profile.maxim }}</p>
</div>
</div>
<div class="answer-stats">5,550 人赞同了该回答</div>
<div class="answer-txt">
{% autoescape false %}
{{ answer.content|safe }}
{% endautoescape %}
</div>
<div class="answer-time">发布于{{ answer.created_at }}</div>
<!-- 底部菜单 -->
<div class="qa-footer">
<div>
<button type="button" class="btn btn-info btn-sm">
<i class="glyphicon glyphicon-thumbs-up"></i> 赞同 {{ answer.love_count }}</button>
<button type="button" class="btn btn-info btn-sm"><i
class="glyphicon glyphicon-thumbs-down"></i></button>
</div>
<div class="txt-menu"><i class="glyphicon glyphicon-comment"></i> 113条评论</div>
<div class="txt-menu"><i class="glyphicon glyphicon-send"></i>分享</div>
<div class="txt-menu"><i class="glyphicon glyphicon-heart"></i>收藏</div>
<div class="txt-menu"><i class="glyphicon glyphicon-flag"></i>举报</div>
<div class="txt-menu"></div>
<div class="txt-menu btn-group">
<i class="glyphicon glyphicon-option-horizontal dropdown-toggle" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false"></i>
<ul class="dropdown-menu">
<li><a href="#">不感兴趣</a></li>
</ul>
</div>
</div>
<!-- // 底部菜单 -->
<!-- 评论框 -->
<div class="comment-box box-wrap">
<!-- 统计和菜单 -->
<div class="comment-stats">
<div class="title">{{ answer.comment_count|d('0', True) }}条评论</div>
<div class="menu"><i class="glyphicon glyphicon-random"></i>切换为时间顺序</div>
</div>
<!-- // 统计和菜单 -->
<!-- 评论列表 -->
<div class="comment-ls" id="id-comment-ls">
<p>内容正在加载中</p>
</div>
<!-- // 评论列表 -->
<nav aria-label="...">
<ul class="pager">
<li class="previous"><a href="javascript:;"><span aria-hidden="true">&larr;</span>
上一页</a></li>
<li class="next"><a href="javascript:void(0);">下一页 <span
aria-hidden="true">&rarr;</span></a></li>
</ul>
</nav>
<!-- 发表评论 -->
<form class="form-horizontal comment-publish">
<input type="text" name="content" class="form-control" placeholder="写下你的评论...">
<button type="button" class="btn btn-default btn-grey">发布</button>
</form>
<!-- // 发表评论 -->
</div>
<!-- // 评论框 -->
</div>
{% else %}
<div class="answer-content box-wrap">
暂无人回答该问题
</div>
{% endif %}
<!-- // 回答内容区域 -->
{{ self.link_more() }}
</div>
<div class="col-md-3 right-content">
<!-- 关于作者 -->
<div class="about-user box-wrap">
<div class="user-info">
<div class="avater">
<img src="/assets/home/qa/user_head.jpg" alt="用户头像">
</div>
<div class="desc">
<h4>舒大克</h4>
<p>《互联网营销人实战手记》新书上市; 公众号:舒大克。</p>
</div>
</div>
<!-- 用户统计 -->
<div class="qa-stats">
<div>
<span>回答</span>
<strong>309</strong>
</div>
<div>
<span>文章</span>
<strong>40</strong>
</div>
<div>
<span>关注者</span>
<strong>85,265</strong>
</div>
</div>
<!-- // 用户统计 -->
<div class="menu-ls">
<div>
<a href="#" class="btn btn-info btn-sm"><i class="glyphicon glyphicon-plus"></i>关注他</a>
</div>
<div>
<a href="#" class="btn btn-default btn-sm btn-grey"><i
class="glyphicon glyphicon-comment"></i>发私信</a>
</div>
</div>
</div>
<!-- //关于作者 -->
<!-- 相关问题 -->
<div class="rel-ques box-wrap">
<div class="title">相关问题</div>
<div class="rel-que-ls">
<div>
<a href="#">疫情过后,你会报复性消费吗?</a><span>30 个回答</span>
</div>
<div>
<a href="#">疫情过后你最想去哪?和谁一起?</a><span>19 个回答</span>
</div>
<div>
<a href="#">如果能熬过这波疫情,你最想做的事情是什么?</a><span>21 个回答</span>
</div>
<div>
<a href="#">请问这次疫情可能有积极影响吗?</a><span>9 个回答</span>
</div>
<div>
<a href="#">如果疫情结束了你最想做什么?</a><span>3 个回答</span>
</div>
</div>
</div>
<!-- //相关问题 -->
<!-- 右侧页脚 -->
<div class="right-footer">
<a href="#">用户指南</a><span class="dot">·</span>
<a href="#">用户使用协议</a><span class="dot">·</span>
<a href="#">用户隐私权政策</a>
<br/>
<a href="#">侵权举报</a><span class="dot">·</span>
<a href="#">网上有害信息举报专区</a>
<br/>
<a href="#">京ICP证 第10001000号</a>
<br/>
<a href="#">京ICP备 第10001000号</a>
<br/>
<a href="#">联系我们 &copy; 2020在线问答</a>
</div>
<!-- //右侧页脚 -->
</div>
</div>
</div>
</div>
<div class="layout-footer">
<a href="#" data-toggle="tooltip" title="意见反馈"><i class="glyphicon glyphicon-briefcase"></i></a>
<a href="#" data-toggle="tooltip" title="回到顶部"><i class="glyphicon glyphicon-arrow-up"></i></a>
</div>
<!-- 写回答,对话框 -->
<div class="modal fade" id="addComment" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<form class="form-horizontal modal-dialog" role="document"
method="post" action="{{ url_for('qa.detail', q_id=question.id) }}">
{{ form.csrf_token }}
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">写回答</h4>
</div>
<div class="modal-body">
<div class="form-group">
{{ form.content }}
{{ ckeditor.load() }}
{{ ckeditor.config(name='content') }}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
<button type="submit" class="btn btn-primary">提交</button>
</div>
</div>
</form>
</div>
<!-- // 写回答,对话框 -->
{% endblock %}
{% block js_inline %}
// 点击,查看更多,把详细的那个p标签展示出来,把自己隐藏
$('.show-desc').click(function () {
$(this).addClass('hidden');
$(this).next().removeClass('hidden')
})
$('.show-all').click(function () {
$(this).addClass('hidden');
$(this).prev().removeClass('hidden')
})
{% endblock %}
{% block js_extra %}
<script>
$(function () {
/**
* 绑定评论的表单提交对象
* @param html
*/
function bindCommentPublishEvent(html) {
let form = $('.comment-publish', html);
$('.btn', form).click(function () {
let _form = $(this).parent();
let content = $('input[name=content]', _form);
let data = _form.serialize();
$.ajax({
url: '{{ url_for("qa.comments", answer_id=answer.id) }}',
method: 'post',
data: data,
complete: function (res) {
console.log('res:', res)
if (res.status === 201) {
window.alert('评论成功');
content.val('')
} else if (res.status === 400) {
window.alert(res.responseJSON.message);
} else {
window.alert('请求失败, 请稍后重试');
}
}
})
})
}


// 评论回复按钮事件
function bindReplyEvent(html) {
$('.link-reply', html).click(function () {
let _id = $(this).data('id');
let _form = $('#id-comment-' + _id);
_form.removeClass('hidden');
});
}

/**
* 绑定点赞事件
* @param html
*/
function bindCommentLoveEvent(html) {
$(".link-love", html).click(function () {
let _this = $(this);
let url = $(this).data('url');
$.ajax({
url: url,
method: 'post',
data: {},
complete: function (res) {
console.log('res:', res)
if (res.status === 201) {
window.alert('点赞成功');
let count = $('span', _this).text();
count = parseInt(count) + 1;
$('span', _this).text(count)
} else if (res.status === 401) {
window.alert('请登录');
window.location.href = '{{ url_for("accounts.login") }}';
} else {
window.alert('服务器正忙')
}
}
})
})
}


// 评论列表的异步加载
let coment_ls = $('#id-comment-ls');
let page = 1;

function loadPageData(page) {
page = page || 1
$.ajax({
url: '{{ url_for("qa.comments", answer_id=answer.id) }}',
method: 'get',
data: {
page: page
},
complete: function (res) {
if (res.status === 200) {
let result = res.responseJSON;
if (result.code === 0) {
let html = $(result.data);
// 绑定回复事件
bindReplyEvent(html);
bindCommentPublishEvent(html);
// 绑定评论点赞事件
bindCommentLoveEvent(html);
coment_ls.empty().append(html)
} else {

}
} else {
window.alert('服务器正忙')
}
}
})
}

$('.pager .previous').click(function () {
page = page - 1;
loadPageData(page);
})
$('.pager .next').click(function () {
page = page + 1;
loadPageData(page);
});
// 默认加载第一页数据
loadPageData(page);
})
</script>
{% endblock %}



正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕美 2021-04-25 11:41:32

同学,你好!发布评论功能的bindCommentPublishEvent()函数只在异步加载评论时调用了,因此点击图二位置的评论是没有办法发布的

图一:

http://img1.sycdn.imooc.com//climg/6084e3a9091a194609150660.jpg

图二:

http://img1.sycdn.imooc.com//climg/6084e3c90965f0c808440502.jpg

解决方法:需要再调用一下发布评论功能函数即可

http://img1.sycdn.imooc.com//climg/6084e4ce09fee6cd07760574.jpg

http://img1.sycdn.imooc.com//climg/6084e44c09aab10007500461.jpg


祝学习愉快!

  • 提问者 MaxLu #1

    添加之后还是不能正常运行,查看网页源代码的时候发现 {% block js_extra %} 下的 js 代码没有运行到, follow.html 里面也存在相同的问题

    2021-04-26 17:59:59
  • 好帮手慕美 回复 提问者 MaxLu #2

    同学,你好!同学可以看下js代码所在的block对应的名字与继承的父模板中是否一致。同学可以参照课程源码,对比相应的代码看是否写错了

    祝学习愉快!

    2021-04-26 19:01:13
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师