本節我們要爲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>