目标:路由到单个文章/博客帖子并包含分页(使用SQL-Alchemy),以便用户可以轻松导航到之前和之后的帖子。
目前,我有以下内容:
@app.route('/articles/ind/<int:id>', endpoint='article')
def indarticle(id = 1):
posts= Post.query.paginate(id, 1, False)
return render_template('article.html',
title = "Article",
posts = posts)
可以看出,我每页显示一篇文章,因此假设文章从ID = 1开始,ID和页码匹配。但是,如果它们不匹配(或从数据库中删除文章),则路由和呈现的页面不匹配。我可以轻松地遍历表格的行,找到哪个页码对应正确的文章ID;然而,这看起来并不高效或实用。
解决这个问题的最佳方法是什么?
更新: 迭代下面的答案,我创建了以下内容:
models.py
class Post(db.Model):
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(100))
body = db.Column(db.Text)
timestamp = db.Column(db.DateTime)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def get_count(self):
return db.session.query(Post).count()
def prev_post(self):
count = self.get_count()
pid = self.id
while (count > 0):
prev_post = None
pid = pid - 1
if db.session.query(Post).get(pid) is not None:
prev_post = db.session.query(Post).get(pid)
break
else:
count = count - 1
return prev_post
def next_post(self):
count = self.get_count()
pid = self.id
while (count > 0):
next_post = None
pid = pid + 1
if db.session.query(Post).get(pid) is not None:
next_post = db.session.query(Post).get(pid)
break
else:
count = count - 1
return next_post
def has_prev(self):
return True if self.prev_post() is not None else False
def has_next(self):
return True if self.next_post() is not None else False
通过这种方式,我可以获得下一篇文章,上一篇文章,以及轻松检查它们是否存在,就像flask-sqlalchemy如何处理分页一样。
答案 0 :(得分:1)
为了确保我们谈论同样的事情,有两种类型的分页....
首先,Flask支持的那种....调用所有文章并在每页显示X个帖子......
其次,你是一个职位,想要前进和后退。
听起来你想要做第二种。
我所做的是在我的POST模型中编写两个静态方法,找出上一个和下一个帖子......然后我通过我的视图函数将值传递给模板。
POST模型staticmethods
<强> MODEL 强>
@staticmethod
def prev_post(pid):
count = Post.get_count()
while (count > 0):
prev_post = None
pid = pid - 1
if db.session.query(Post).get(pid) is not None:
prev_post = db.session.query(Post).get(pid)
break
else:
count = count - 1
return prev_post
@staticmethod
def next_post(pid):
count = Post.get_count()
while (count > 0):
next_post = None
pid = pid + 1
if db.session.query(Post).get(pid) is not None:
next_post = db.session.query(Post).get(pid)
break
else:
count = count - 1
return next_post
prev_post功能的工作原理。
当然,下一个函数完全相同,除了你+1 pid而不是-1。
这解决了删除帖子和显示错误号码的问题。另外,请注意我不必返回所有帖子并循环播放它们。我只是得到一个计数,并检查pid是否一次存在一个。在我获得命中之前,我很少经历超过2或3个循环,因为循环始终相对于当前帖子开始。简而言之,此过程使用相对少量的内存。
现在我可以在我看来调用这些函数......
查看强>
@app.route('/<path:url>', methods=['GET', 'POST']) def
display_post(url):
post = Post.get_post(url)
next_post = Post.next_post(post.id)
prev_post = Post.prev_post(post.id)
return render_template('post.html',
next=next_post, prev=prev_post, post=post)
这是模板。
<强>模板强>
{% extends "base.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<H2>{{ post.title }}</H2>
<b>Posted {{ post.pub_date|dts }} in <a href="{{ url_for('display_topic', url=post.topic.url) }}">{{post.topic}}</a></b>
{{post.body|markdown}}
{% if prev.url is defined %}
<a href="{{ url_for('display_post', url=prev.url) }}"><<< {{prev.title}}</a>
{% endif %}
{% if prev.url is not defined and next.url is not defined %}{% else %} | {% endif %}
{% if next.url is defined %}
<a href="{{ url_for('display_post', url=next.url) }}">{{next.title}} >>></a>
{% endif %}
{% if current_user.is_authenticated() %}
<p><a href="{{ url_for('edit_post', url=post.url) }}">edit</a></p>
<p><a href="{{ url_for('delete_post', url=post.url) }}">delete</a></p>
{% endif %}
{% endblock %}
如果存在next或prev帖子,模板仅显示链接。