用户动态的分页
应用看起来更完善了,但是在主页显示所有用户动态迟早会出问题。如果一个用户有成千上万条关注的用户动态时,会发生什么?你可以想象得到,管理这么大的用户动态列表将会变得相当缓慢和低效。
为了解决这个问题,我会将用户动态进行分页。这意味着一开始显示的只是所有用户动态的一部分,并提供链接来访问其余的用户动态。Flask-SQLAlchemy 的 paginate()
方法原生就支持分页。例如,我想要获取用户关注的前 20 个动态,我可以将 all()
结束调用替换成如下的查询:
>>> user.followed_posts().paginate(1, 20, False).items
Flask-SQLAlchemy 的所有查询对象都支持 paginate
方法,需要输入三个参数来调用它:
- 从 1 开始的页码
- 每页的数据量
- 错误处理布尔标记,如果是
True
,当请求范围超出已知范围时自动引发 404 错误。如果是False
,则会返回一个空列表。
paginate
方法返回一个 Pagination
的实例。其 items
属性是请求内容的数据列表。 Pagination
实例还有一些其他用途,我会在之后讨论。
现在想想如何在 index()
视图函数展现分页呢。我先来给应用添加一个配置项,以表示每页展示的数据列表长度吧。
class Config(object):
# ...
POSTS_PER_PAGE = 3
存储这些应用范围的“可控机关”到配置文件是一个好主意,因为这样我调整时只需去一个地方。 在最终的应用中,每页显示的数据将会大于三,但是对于测试而言,使用小数字很方便。
接下来,我需要决定如何将页码并入到应用 URL 中。 一个相当常见的方法是使用 查询字符串 参数来指定一个可选的页码,如果没有给出则默认为页面 1。 以下是一些示例网址,显示了我将如何实现这一点:
- 第 1 页,隐含: http://localhost:5000/index
- 第 1 页,显式: http://localhost:5000/index?page=1
- 第 3 页: http://localhost:5000/index?page=3
要访问查询字符串中给出的参数,我可以使用 Flask 的 request.args 对象。 你已经在 第五章 中看到了这种方法,我用 Flask-Login 实现了用户登录的可以包含一个 next
查询字符串参数的 URL。
给主页和发现页的视图函数添加分页的代码变更如下:
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@login_required
def index():
# ...
page = request.args.get('page', 1, type=int)
posts = current_user.followed_posts().paginate(
page, app.config['POSTS_PER_PAGE'], False)
return render_template('index.html', title='Home', form=form,
posts=posts.items)
@app.route('/explore')
@login_required
def explore():
page = request.args.get('page', 1, type=int)
posts = Post.query.order_by(Post.timestamp.desc()).paginate(
page, app.config['POSTS_PER_PAGE'], False)
return render_template("index.html", title='Explore', posts=posts.items)
通过这些更改,这两个路由决定了要显示的页码,可以从 page
查询字符串参数获得或是默认值 1。然后使用 paginate()
方法来检索指定范围的结果。 决定页面数据列表大小的 POSTS_PER_PAGE
配置项是通过 app.config
对象中获取的。
请注意,这些更改非常简单,每次更改都只会影响很少的代码。 我试图在编写应用每个部分的时候,不做任何有关其他部分如何工作的假设,这使我可以编写更易于扩展和测试的且兼具模块化和健壮性的应用,并且不太可能失败或出现 BUG。
来尝试下分页功能吧。 首先确保你有三条以上的用户动态。 在发现页面中更方便测试,因为该页面显示所有用户的动态。 你现在只会看到最近的三条用户动态。 如果你想看接下来的三条,请在浏览器的地址栏中输入 http://localhost:5000/explore?page=2 。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论