帖子详情

动态加载帖子详情数据

在 blueprints/post.py 中,添加 post_detail 视图函数,代码如下。

@bp.get("/post/detail/<int:post_id>")
def post_detail(post_id):
    post = PostModel.query.get(post_id)
    post.read_count += 1
    db.session.commit()
    return render_template("front/post_detail.html", post=post)

上述代码中,在 URL 中定义了一个 post_id 参数,然后提取帖子对象,并且把帖子对象传到了 post_detail.html 模板中。为了能访问帖子详情,首先要在首页的帖子列表中补齐帖子标题的超链接,代码如下。

<p class="post-title">
    <a href="{{ url_for('front.post_detail', post_id=post.id) }}">
        {{ post.title }}
    </a>
</p>

在帖子详情页中,把帖子相关的数据填充进去,如发表时间、作者等,代码如下。

...
<div class="post-container">
    <h2>{{ post.title }}</h2>
    <p class="post-info-group">
        <span>发表时间:{{ post.create_time }}</span>
        <span>作者:{{ post.author.username }}</span>
        <span>所属板块:{{ post.board.name }}</span>
        <span>阅读数:{{ post.read_count }}</span>
        <span>评论数:{{ post.comments|length }}</span>
    </p>
    <article class="post-content" id="post-content">
        {{ post.content|safe }}
    </article>
</div>
...

现在重新加载帖子详情页面,可以看到帖子数据都能正常显示在页面中了。

发布评论

在帖子详情页面底部有一个 textarea 文本框,用于发布帖子评论。在 forms/post.py 中实现一个评论表单功能,代码如下。

class PublicCommentForm(BaseForm):
    content = StringField(validators=[Length(
        min=2, max=200, message="请输入正确长度的评论!")])

上述代码中,定义了 content 字段,发布评论只需要提交评论内容即可。然后在 blueprints/front.py 中,添加一个 public_comment 视图函数,并添加以下代码。

@bp.post("/post/<int:post_id>/comment")
@login_required
def public_comment(post_id):
    form = PublicCommentForm(request.form)
    if form.validate():
        content = form.content.data
        comment = CommentModel(content=content, post_id=post_id, author=g.user)
        db.session.add(comment)
        db.session.commit()
    else:
        for message in form.messages:
            flash(message)
    return redirect(url_for("front.post_detail", post_id=post_id))

上述代码中,我们把帖子 id 通过 URL 参数传过来,然后通过表单获取评论内容。发布评论的视图函数必须在登录的条件下才能访问,因此加了 login_required 装饰器。然后通过 g.user 即可获取到当前登录的用户作为该条评论的作者。评论发表成功,则重新加载帖子详情页面,这样用户就能看到最新的评论数据。评论发表失败,则把表单错误信息传到 flash 中,同时重新加载页面来显示错误信息。在 templates/front/post_detail.html 中添加显示错误信息和表单 URL,代码如下。

image 2025 01 22 16 18 16 877

接着在 templates/front/post_detail.html 中,把帖子所有的评论循环显示出来,代码如下。

image 2025 01 22 16 18 41 402

现在重新访问任何一篇帖子的详情页,在登录的情况下都可以正常发表评论了。但是,新发表的评论会显示在帖子列表的后面,为了实现通过 post.comments 获取的评论列表能根据发表时间倒序排序,在 CommentModel 中将 post 的 relationship 代码修改如下。

...
post = db.relationship("PostModel", backref=db.backref('comments', order_by=create_time.desc()))
...

这样,就可以自动按照评论发表时间倒序排序了。