bluelog icon indicating copy to clipboard operation
bluelog copied to clipboard

关于评论数目的可改进实现

Open jiangyanglinlan opened this issue 7 years ago • 6 comments

  1. 主页每篇文章显示的评论数是这篇文章下的所有评论(包括未审核通过的), 主要代码如下:
{{ post.comments|length }}
  1. 文章详情页面显示的评论数是分页后当前页面的评论数, 而不是文章的总评论数, 主要的代码如下:
post = Post.query.get_or_404(post_id)
page = request.args.get('page', 1, type=int)
per_page = current_app.config['BLUELOG_COMMENT_PER_PAGE']
pagination = Comment.query.with_parent(post).filter_by(reviewed=True).order_by(Comment.timestamp.asc()).paginate(page, per_page)
comments = pagination.items
{{ comments|length }} Comments

解决方法:

我的实现是在 Post 类中新增了一个方法, 返回审核通过的评论列表:

class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(60))
    body = db.Column(db.Text)
    timestamp = db.Column(db.DateTime, default=datetime.now)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    comments = db.relationship('Comment', backref='post', cascade='all, delete-orphan')

    def reviewed_comments(self):
        return [comment for comment in self.comments if comment.reviewed is True]

这样的话, 在需要显示评论数量的地方就可以使用 {{ post.reviewed_comments()|length }}。

jiangyanglinlan avatar Oct 18 '18 11:10 jiangyanglinlan

作者好像没错把,filter_by(reviewed=True),都把未审核的过滤去了

goodbad3 avatar Nov 22 '18 01:11 goodbad3

@goodbad3 错误的是主页文章列表中显示的评论数量,这里没有过滤。

greyli avatar Nov 22 '18 02:11 greyli

那不就成了pagination.toal了。难道不是要每一页的评论数? @greyli , @jiangyanglinlan

goodbad3 avatar Nov 22 '18 13:11 goodbad3

文章页面的评论数字一般来说是应该显示总数的,这里的确可以用 pagination.total

greyli avatar Nov 22 '18 14:11 greyli

备注一下。第 2 个问题已修复(54b9c0d)并将在第 2 次重印更新。

第 1 个问题因为涉及较大源码变动,暂时不修复,如果有第 2 版,再考虑更新书里的内容并修复。另外那个获取已审核评论的方法可以直接返回数量,作为属性使用,比如:

class Post(db.Model):
    # ...
    
    @property
    def reviewed_comments_count(self):
        return len([comment for comment in self.comments if comment.reviewed])

这样在模板里可以直接使用 {{ post.reviewed_comments_count }}

greyli avatar Mar 05 '19 08:03 greyli

看书至此也发现了同样的问题,我的解决办法是在工厂函数里注册了一个过滤器,过滤掉未通过审核的评论数,主页里渲染出的评论数量就能与文章页显示的评论数一致了,代码如下:

# 自定义过滤器函数
def register_template_filter(app):
    @app.template_filter()
    def reviewed(obj):
        num = 0
        for comment in obj:
            if comment.reviewed:
                num += 1
        return num

def create_app(*args, **kwargs):
    #...

    # 工厂函数里注册模板过滤器
    register_template_filter(app)  
    return app

然后再到模板里直接渲染:{{ post.comments|reviewed }}

BrightHsu avatar May 27 '20 10:05 BrightHsu

感谢反馈,已在 https://github.com/greyli/new-bluelog/pull/14 处理。

greyli avatar Sep 17 '23 15:09 greyli