本节我们要为Web程序添加显示和提交评论的功能。
一. 创建Comment表
评论存在数据库中,因此我们要创建一个Comment表来存储评论:
class Comment(db.Model):
__tablename__ = 'comments'
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
body_html = db.Column(db.Text)
disabled = db.Column(db.Boolean)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('users.id'))
post_id = db.Column(db.Integer, db.ForeignKey('posts.id'))
class User(UserMixin, db.Model):
#...
comments = db.relationship('Comment', backref='user', lazy='dynamic')
class Post(db.Model):
#...
comments = db.relatonship('Comment', backref='post', lazy='dynamic')
User表和Post表与Comment表都是一对多的关系。
二. 文章页面
评论一般都显示在文章页面, 文章页面的布局类似下面这样子:
首先是文章, 然后是评论区, 评论区包括标题, 评论表单还有评论列表, 最后是页面导航。
因此post.html页面的内容是:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "_macros.html" as macros%}
{% block title %}Flasky - Post{% endblock %}
{% block page_content %}
{% include "_posts.html" %}
<h4>Comments</h4>
{% if current_user.can(Permission.COMMIT) %}
<div class="comment-form">
{{ wtf.quick_form(form) }}
</div>
{% endif %}
{% include "_comments.html" %}
{% if pagination %}
<div class="pagination">
{{ macros.pagination_widget(pagination, 'main.post', id=posts[0].id, fragment='#comments')}}
</div>
{% endif %}
{% endblock %}
三. 处理请求的路由函数
有了数据表和文章页面, 我们还需要一个路由函数来显示页面并处理提交的评论:
@main.route('/post/<int:id>', methods=['GET', 'POST'])
def post(id):
post = Post.query.get_or_404(id)
form = CommentForm()
if form.validate_on_submit():
comment = Comment(body=form.body.data, post=post, author=current_user._get_current_object())
db.session.add(comment)
flash('Your comment has been published.')
return redirect(url_for('.post', id=post.id, page=-1))
page = request.args.get('page', 1, type=int)
if page == -1:
page = (post.comments.count() - 1)/ \
current_app.config['FLASKY_COMMENTS_PER_PAGE'] + 1
pagination = post.comments.order_by(Comment.timestamp.asc()).paginate(page, per_page=current_app.config['FLASKY_COMMENTS_PER_PAGE'], error_out=False)
comments = pagination.items
return render_template('post.html', posts=[post], form=form, comments=comments, pagination=pagination)
四. 链接到博客文章的评论
<a href="{{ url_for('main.post', id=post.id)}}#comments">
<span class="label label-primary">
{{ post.comments.count() }} Comment
</span>
</a>