bluelog
bluelog copied to clipboard
关于评论数目的可改进实现
- 主页每篇文章显示的评论数是这篇文章下的所有评论(包括未审核通过的), 主要代码如下:
{{ post.comments|length }}
- 文章详情页面显示的评论数是分页后当前页面的评论数, 而不是文章的总评论数, 主要的代码如下:
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 }}。
作者好像没错把,filter_by(reviewed=True),都把未审核的过滤去了
@goodbad3 错误的是主页文章列表中显示的评论数量,这里没有过滤。
那不就成了pagination.toal了。难道不是要每一页的评论数? @greyli , @jiangyanglinlan
文章页面的评论数字一般来说是应该显示总数的,这里的确可以用 pagination.total。
备注一下。第 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 }}。
看书至此也发现了同样的问题,我的解决办法是在工厂函数里注册了一个过滤器,过滤掉未通过审核的评论数,主页里渲染出的评论数量就能与文章页显示的评论数一致了,代码如下:
# 自定义过滤器函数
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 }}
感谢反馈,已在 https://github.com/greyli/new-bluelog/pull/14 处理。