2,689

Flask前端数据分页展示(实例)

最近刚好遇到关于数据库含有大批量数据,而又不想在前端渲染时一次性加载出来,数据少的时候还好,一旦数据几千几万甚至更为攀大时,会让前端页面变得卡顿,体验很差,然后就上网查找资料,找到一个基于flask的的分页函数paginate,既能根据自己自定义前端显示条目,系统会自行去分页,该工具也被称为分页器。

首先来介绍一下这个分页器,paginate() 方法的返回值是一个 Pagination 类对象,这个类在 Flask-SQLAlchemy 中定义。 这个对象包含很多属性,用于在模板中生成分页链接,因此将其作为参数传入了模板。分页器的属性如下:

items 	    -------- 当前页中的记录,即当页数据
query 	    -------- 分页的源查询
page  	    -------- 当前页数
prev_num    -------- 上一页的页数
next_num    -------- 下一页的页数
has_next    -------- 是否含有下一页,返回布尔型
has_prev    -------- 是否含有下一页,返回布尔型
pages       -------- 查询得到总页数
per_page    -------- 每页显示的条目数
total       -------- 查询返回的记录总数

分页器的方法如下:

iter_pages()-------- 动态返回分页的导航中的页数列表
prev()      -------- 上一页的分页对象
next()      -------- 下一页的分页对象

接下来介绍一下后台的视图处理函数,本文以获取订单信息为例,代码如下:

@order.route('/')
@login_required
def index():
    #这里的page就是前端我们点击的第几页,以GET请求到这里,其中的1位默认值
    #type就是给page添加一个默认数据类型
    page=request.args.get('page', 1, type=int)
    #这里的orderNum就是前端的当页显示条目数,同样也是GET请求到这里
    #同样给个默认值100,默认属性为int
    #这里的type主要是为了保证参数无法转换成整数时,返回默认值
    #一开始我在这里手动转类型一直出错,只有用type给默认才得以解决
    orderNum = request.args.get('orderNum', 100, type=int)
    stores = Store.query.all()
    #这里的order_by及时对获取的订单进行降序(desc()),补充一下升序为(acs())
    #paginate则是核心,传入页码数,1页面显示条目数
    pagination=Order.query.order_by(Order.id.desc()).paginate(page, per_page=orderNum, error_out=False)
    #渲染时把pagination以及显示条目数返回到前端
    return render_template('order/index.html', pagination=pagination, stores=stores, orderNum=orderNum)

介绍完视图,接下来介绍一下分页导航模板,本文以宏模板作为导航栏的基础模型(pagination.html),代码如下:

{% macro pagination_widget(pagination, endpoint, orderNum) %}
    < div class="col-lg-12">
        < div class="panel-wrapper collapse in">
            < div class="panel-body">
                < div class="row">
                    < div class="col-md-12">
                        < ul class="pagination pagination-split">
                            < li{% if not pagination.has_prev %} class="disabled"{% endif %}> < a href="{% if pagination.has_prev %}{{ url_for(endpoint,page = pagination.page - 1, orderNum = orderNum, **kwargs) }}
            {% else %}#{% endif %}">< i class="fa fa-angle-left">< /i>< /a> < /li>
                            {% for p in pagination.iter_pages() %}
                                {% if p %}
                                    {% if p == pagination.page %}
                                    < li class="active">
                                        < a href="{{ url_for(endpoint, page = p, orderNum = orderNum, **kwargs) }}">{{ p }}< /a>
                                    < /li>
                                    {% else %}
                                    < li>
                                        < a href="{{ url_for(endpoint, page = p, orderNum = orderNum, **kwargs) }}">{{ p }}< /a>
                                    < /li>
                                    {% endif %}
                                {% else %}
                                < li class="disabled">
                                    < a href="#">< i class="fa fa-ellipsis-h">< /i>< /a>
                                < /li>
                                {% endif %}
                            {% endfor %}
                            < li{% if not pagination.has_next %} class="disabled"{% endif %}>
                                < a href="{% if pagination.has_next %}{{ url_for(endpoint,page = pagination.page + 1,orderNum = orderNum, **kwargs) }}{% else %}#{% endif %}">< i class="fa fa-angle-right">< /i>< /a>
                            < /li>
                        < /ul>
                    < /div>
                < /div>
            < /div>
        < /div>
    < /div>
{% endmacro %}

其中分页宏模板的参数有三个,分别是分页对象,路径,当页显示的条目数,刚刚视图函数中返回显示条目数就是为了这里调用,一开始我没传这个参数,当前端转换显示条目数时,会返回默认显示条目数。最后对于分数的显示,即实例化宏模板到指定区域即可,如下:

{% from "macros/pagination.html" import pagination_widget%}  
 
< div class="pagination  pull-right">
       {{ pagination_widget(pagination, '.index', orderNum) }}
< /div>

最后就是对于前端记录的渲染,直接用:

{% for item in pagination.items %}
{% endfor %}

就可以获取当前页面的条目,然后循环渲染到前端即可。最后我们看到的前台地址变化为:

原页面路径+?page=当前页数&orderNum=页面显示条目数

发表评论

邮箱地址不会被公开。 必填项已用*标注