本节我们要为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>