如果,某人的博客文章比较多,在一个页面上显示全部文章,耗时长、看起来也不方便。因此分页是比较好的选择。
首先,我们在测试环境中使用Forgerypy创建一些虚拟数据。依赖文件如何写,参照点击打开链接
# requirements/dev.txt
Forgerypy==0.1
在User类和Post类中添加生成虚拟用户和文章的方法
# app/models.py
class User(Mixin,db.model):
#...
@staticmethod
def generate_fake(count=100):
'''生成虚拟用户'''
from sqlalchemy.exc import IntegrityError
from random import seed
import forgery_py
seed()
for i in range(count):
u = User(email=forgery_py.internet.email_address(),
username=forgery_py.internet.user_name(True),
password=forgery_py.lorem_ipsum.word(),
name=forgery_py.name.full_name(),
location=forgery_py.address.city(),
about_me=forgery_py.lorem_ipsum.sentence(),
member_since=forgery_py.date.date(True))
db.session.add(u)
try:
db.session.commit()
except IntegrityError:
db.session.rollback()
# app/models.py
class Post(db.Model):
#...
@staticmethod
def generate_fake(count=100):
'''生成测试用的假文章'''
from random import seed, randint
import forgery_py
seed()
user_count = User.query.count()
for i in range(count):
u = User.query.offset(randint(0, user_count-1)).first()
p = Post(body=forgery_py.lorem_ipsum.sentences(randint(1,3)),timestamp=forgery_py.date.date(True),author=u)
db.session.add(p)
db.session.commit()
在python shell中使用User类,Post类生成虚拟用户和文章:
# pyCharm Terminal
python manager.py shell
User.generate_fake(100)
Post.generate_fake(100)
好了,虚拟数据生成完了,下面正式介绍如何对过长的页面进行分页。
# main/views.py
@main.route('/',methods=['GET','POST'])
def index():
'''
视图函数。主页,写博客
:return: 渲染后的模板
'''
page = request.args.get('page', 1, type=int) #type=int,保证参数无法转化为int时返回默认值
pagination = Post.query.order_by(Post.timestamp.desc()).paginate(page, per_page=current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False)
posts = pagination.items
return render_template('index.html',form=form,posts=posts,pagination=pagination)
从request(请求上下文)中获取page的值,默认值为1,默认值类型为int。也就是说,如果没有指定page,page会为1;如果是double,float等可以转为int的,则转为int。
为了显示某页中的记录,要把all()换成Flask-SQLAlchemy(all()就显示全部)提供的paginate()方法,第一个参数是页数(page,这是必须的),第二个参数per_page指定每页的记录数(默认是20),第三个参数是error_out,当其设为True时(默认值),如果请求的页面超出了范围则返回404错误;如果为False则返回空列表。
如果不加分页导航,就要在url上加上?page=2才能显示第二页的内容,普通用户肯定不知道这样的操作。为了对用户更友好,我们要添加分页导航。
paginate()方法的返回值是一个pagination类对象。这个类对象有如下属性和方法:
return render_template('index.html',form=form,posts=posts,pagination=pagination)
通过把pagination类对象传递进index.html就可以使用pagination类对象实现分页导航了。