利用SQLAlchemy和Bootstrap实现数据分页显示
来源:互联网 发布:电脑版淘宝 编辑:程序博客网 时间:2024/04/30 06:59
随着Web业务拓展,数据量会不断增长,如果在一个页面上将全部数据一次性显示出来,服务器和浏览器都会受到很大影响,不切合实际。一般的解决方式是采用分页显示的办法。在Flask框架中,可以利用SQLAlchemy实现分页查询,结合Bootstrap提供的强大CSS分页效果,完美地实现分页导航的效果。
0x01 创建虚拟数据
为了更好地体现显示分页效果,我们先在数据模型中虚拟足够的模拟数据。在Python中,我们可以利用Forgerypy来实现(参见利用ForgeryPy生成虚拟数据)。下面我们直接写两个函数来实现实验数据的生成:
Users.py:
#生成模拟数据@staticmethoddef generate_fake(count=100): from sqlalchemy.exc import IntegrityError from random import seed import forgery_py seed() for i in range(count): u=Users() u.username=forgery_py.internet.user_name(True) u.email=forgery_py.internet.email_address() u.password=forgery_py.lorem_ipsum.word() u.confirmed=True u.about_me=forgery_py.lorem_ipsum.sentence() u.realname=forgery_py.name.full_name() u.location=forgery_py.address.city() u.registerTime=forgery_py.date.date(True) db.session.add(u) try: db.session.commit() except IntegrityError: #回滚 db.session.rollback()
Posts.py:
@staticmethoddef generate_fake(c=100): from random import randint,seed import forgery_py from Users import Users seed() count=db.session.query(Users).count() for i in range(c): u=db.session.query(Users).offset(randint(0,count-1)).first() p=Posts(author=u) p.body=forgery_py.lorem_ipsum.sentence() p.timestamp=forgery_py.date.date(True) db.session.add(p) db.session.commit()
0x02 渲染数据
定义支持分页显示的路由:
#分页显示page=request.args.get('page',1,type=int)pagination=Posts.query.order_by(Posts.timestamp.desc()).paginate( page,per_page=5, error_out=False)posts=pagination.itemsreturn render_template('main/index.html',posts=posts,form=form,pagination=pagination)
通过request.args.get
获取需要显示的页码(type定义为整数,异常默认为1),per_page
定义了每页显示的记录的个数。error_out
参数如果设置成True,当请求的页数超过了总的页数范围,就会返回一个404错误,如果设为False,就会返回一个空列表。这样修改后,页面只会显示有限的记录数量。
0x03 添加分页导航
paginate()
方法返回了一个Pagination对象。这个类在Flask-SQLAlchemy中定义,包含大量属性和方法,可以非常方便地生成分页导航模型。
属性:
方法:
结合Bootstrap提供的分页CSS效果,我们可以实现一个美观的分页导航。定义一个macro宏(/templates/_macros.html
):
{% macro pagination_widget(pagination, endpoint, fragment='') %}<div class="pagination"> <ul class="pagination"> <li{% if not pagination.has_prev %} class="disabled"{% endif %}> <a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}"> « </a> </li> {% for p in pagination.iter_pages() %} {% if p %} {% if p == pagination.page %} <li class="active"> <a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a> </li> {% else %} <li> <a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a> </li> {% endif %} {% else %} <li class="disabled"><a href="#">…</a></li> {% endif %} {% endfor %} <li{% if not pagination.has_next %} class="disabled"{% endif %}> <a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}"> » </a> </li></ul></div>{% endmacro %}
可以在视图模板的适当位置引入这个宏:
{%extends 'base.html'%}{%import 'bootstrap/wtf.html' as wtf%}{%import '_macros.html' as macros%}……{%if pagination%}{{macros.pagination_widget(pagination,'main.index')}}{%endif%}
这样就实现了分页导航的效果:
0x04 功能拓展
我们可以对分页导航进行拓展(参见Bootstrap学习总结笔记(12)– 基本组件之分页)。
_macros.html中添加跳转功能:
{% macro pagination_widget(pagination, endpoint, fragment='') %}<div class="pagination"> <ul class="pagination"> <li{% if not pagination.has_prev %} class="disabled"{% endif %}> <a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}"> « </a> </li> {% for p in pagination.iter_pages() %} {% if p %} {% if p == pagination.page %} <li class="active"> <a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a> </li> {% else %} <li> <a href="{{ url_for(endpoint, page = p, **kwargs) }}{{ fragment }}">{{ p }}</a> </li> {% endif %} {% else %} <li class="disabled"><a href="#">…</a></li> {% endif %} {% endfor %} <li{% if not pagination.has_next %} class="disabled"{% endif %}> <a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{{ fragment }}{% else %}#{% endif %}"> » </a> </li> <li class="pull-right"> <label for="transfer_page">跳转到:</label> <input type="text" class="text-info" size="3" id="transfer_page"> <button type="button" class="btn btn-primary btn-sm" id="transfer">Go</button> </li></ul></div>{% endmacro %}
在视图模板中加入js代码:
{%block scripts%}{{super()}}<script type="text/javascript"> $(function(){ $('#transfer').click(function(){ var page=$('#transfer_page').val(); window.location.href="{{url_for('main.index')}}"+"?page="+page; }) })</script>
效果如下:
- 利用SQLAlchemy和Bootstrap实现数据分页显示
- 利用Flask-SQLAlchemy提供的paginate()方法实现博客文章的分页显示
- 利用Repeater控件实现数据分页显示
- 利用ASP实现Oracle数据记录的分页显示
- 利用ASP实现Oracle数据记录的分页显示
- Bootstrap 分页插件 ajax获取数据显示
- 利用js和css实现Bootstrap下拉列表数据过滤
- 57-005-2 bootstrap实现分页显示
- 利用ThinkPHP实现分页显示
- 利用Struts2和Hibernate实现页面分页显示的功能
- 利用bootstrap进行分页
- DataGridView实现分页显示数据
- Thinkphp 实现数据分页显示
- Struts实现分页显示数据
- 利用Limit完成数据的分页显示
- MyFaces实现分页显示数据和MyFaces整合Sitemesh
- java 三层架构 实现数据的显示和分页功能
- 用jQuery和bootstrap实现分页器
- 沙盒文件
- 手把手入门神经网络系列(2)_74行代码实现手写数字识别
- Kylin构建cube时状态一直处于pending
- Docker的boot2docker.iso镜像使用
- ios tableview去除指定cell分割线
- 利用SQLAlchemy和Bootstrap实现数据分页显示
- 点击tabbarItem添加是否跳转登录页面判断
- HTTP协议详解
- 定时任务组件
- oh my zsh插件
- Java02继承
- Unity3D教学 开发简单版第一人称射击游戏 可以多人联机(附源码)
- Linux_驱动头文件
- 分级聚类算法(集体智慧编程)