预计所需阅读时间:6分钟

用Flask做一个显示项目列表中,通常要加上分页和搜索的功能,而搜索之后的分页功能与默认情况下分页功能的处理是不一样的,需要额外的处理。

以下是用户列表的视图函数:

@admin_app.route('/user/list/', methods=['get', 'post'])
def userList():
    form = UserSearch()
    q = request.args.get('q')  # 搜索条件
    page = request.args.get('page', 1)  # 默认为第1页
    if not q:  # 非空,有搜索词的情况下  
        page = request.args.get('page', 1)
        form_field = request.args.get('field')
        form_sex = request.args.get('sex')
        form_order = request.args.get('order')
        print(q, form_field, form_sex, form_order)
        if form_field == 'username':
            condition = User.username.like('%%%s%%' % q)
        else:
            condition = User.realname.like('%%%s%%' % q)
        if form_order == '1':
            order = User.id.asc()
        else:
            order = User.id.desc()
        if request.args.get('sex') == '0':
            res = User.query.filter(condition).order_by(order).paginate(int(page), 10)
        else:
            res = User.query.filter(condition, User.sex == request.args.get('sex')).order_by(order).paginate(page, 10)
        users = res.items  # 分页项目
        pageList = res.iter_pages()  # 分页列表
        total = res.total  # 项目总数
        pages = res.pages  # 分页总数
        # 有条件搜索和无搜索转到同一模板,用模板语法来区分get的链接
        return render_template('admin/user/user_list.html', users=users, pageList=pageList, pages=pages, total=total, form=form, q=q, field=form_field, sex=form_sex, order=form_order)
    else:
        res = User.query.paginate(int(page), 10)
        users = res.items
        pageList = res.iter_pages()
        total = res.total
        pages = res.pages
        print(q, total)
        return render_template('admin/user/user_list.html', users=users, pageList=pageList, pages=pages, total=total, form=form, q=q)

因为带条件搜索渲染模板时,在分页的跳转转接要带上更多变量,于是可以要这样:return render_template('admin/user/user_list.html', users=users, pageList=pageList, pages=pages, total=total, form=form, q=q, field=form_field, sex=form_sex, order=form_order)

在前端的模板通过判断{% if q == None %},来决定渲染分页跳转代码:

<ul class="pagination">
    {% for page in pageList %}
        {% if page!=None %}
            {% if q == None %}
                <li><a href="?page={{ page }}">{{ page }}</a></li>
            {% else %}
                <li><a href="?page={{ page }}&q={{ q }}&field={{ field }}&sex={{ sex }}&order={{ order }}">{{ page }}</a></li>
            {% endif %}
        {% else %}
            <li><a href="#">...</a></li>
        {% endif %}
    {% endfor %}
</ul>

带条件搜索的分页,除了把pageList对象的page页码渲染出来外,还要把代表借条的变量加入到get的跳转链接里面:
<a href="?page={{ page }}&q={{ q }}&field={{ field }}&sex={{ sex }}&order={{ order }}">{{ page }}a>

这样就可以用一个模板用get的方式,解决原来条件搜索后有多个分页,按第2之后的分页会跳回不带条件搜索的问题。