美文网首页
05-Flask之数据查询(分页)

05-Flask之数据查询(分页)

作者: 郑元吉 | 来源:发表于2018-11-14 17:25 被阅读3次

    一、批量数据产生(数据库存储过程)

    # 商品列表表
    # 商品模型类
    class Goods(db.Model):
        # 商品id,主键
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        # 商品名称
        name = db.Column(db.String(20))
        # 商品图片
        icon = db.Column(db.String(255))
        # 商品价格
        price = db.Column(db.Integer)
        # 商品描述
        detail = db.Column(db.String(255))
    
    
    # 表单结构goods
    mysql> desc goods;
    +--------+--------------+------+-----+---------+----------------+
    | Field  | Type         | Null | Key | Default | Extra          |
    +--------+--------------+------+-----+---------+----------------+
    | id     | int(11)      | NO   | PRI | NULL    | auto_increment |
    | name   | varchar(20)  | NO   |     | NULL    |                |
    | icon   | varchar(255) | NO   |     | NULL    |                |
    | price  | int(11)      | NO   |     | NULL    |                |
    | detail | varchar(255) | NO   |     | NULL    |                |
    +--------+--------------+------+-----+---------+----------------+
    5 rows in set (0.00 sec)
    
    
    
    # 存储过程: 创建商品数据
    # insert into goods(name,icon,price,detail) value(name,icon,price,detail)
    delimiter //
    create procedure add_goods(num int(4))
    begin
        # 定义变量
        declare _i,_price,_temp int(4) default 0;
        declare _name,_icon,_detail varchar(255) default '';
        declare BASE_PATH varchar(255) default '/static/img/';
    
        # 循环
        while _i<num do
            # 设置变量
            set _temp = round(rand()*10000+1000);
            set _name = concat(_temp,'-商品名称');
            set _temp = round(rand()*5+1);
            case _temp
            when 1 then
                set _icon = concat(BASE_PATH,'1.jpg');
            when 2 then
                set _icon = concat(BASE_PATH,'2.jpg');
            when 3 then
                set _icon = concat(BASE_PATH,'3.jpg');
            when 4 then
                set _icon = concat(BASE_PATH,'4.jpg');
            when 5 then
                set _icon = concat(BASE_PATH,'5.jpg');
            when 6 then
                set _icon = concat(BASE_PATH,'6.jpg');
            else
                set _icon = concat(BASE_PATH,'1.jpg');
            end case;
            set _temp = round(rand()*10000+1000);
            set _price = _temp;
            set _temp = round(rand()*10000+1000);
            set _detail = concat(_temp,'-Apple/苹果 iPhone 7 Plus苹果7代7pluss国行美版三网5.5寸7p手机');
    
            # 插入数据
            insert into goods(name,icon,price,detail) value(_name,_icon,_price,_detail);
    
            # 修改次数
            set _i = _i + 1;
        end while;
    
        # 显示数据
        select * from goods;
    end
    //
    delimiter ;
    
    
    # 调用存储过程
    call add_goods(30);
    

    备注: 存储过程的添加是要在表单对应的数据库中进行操作!!!

    二、SQLAlchemy数据查询之分页操作(手动)

    • 手动操作(自己查询关联)
    @blue.route('/goodslist/<int:num>/<int:per>/')
    def goodslist(num,per):
        # 第num页
        # 每页显示per行
        goods = Goods.query.offset((num-1) * per).limit(per)
        
        return render_template('goodslist.html', goods=goods
    
    • flask自带(paginate)
    - 当前页面(属性)
        page  
    - 当前页面中的记录(属性)
        items
    - 上一页页码(属性)
        prev_num
    - 下一页页码(属性)
        next_num
    - 如果有上页返回True(属性)
        has_prev
    - 如果有下页返回True(属性)
        has_next
    - 查询得到总页数(属性)
        pages
    - 每一页显示记录的数量(属性)
        per_page  
    - 查询返回的记录总数(属性)
        total
        
    - 返回一个分页导航中显示列表
        iter_pages
        
        这个列表最左边左边显示left_edeg页,
        当前页的左边显示left_current页,
        当前页的右边显示right_current页,
        最右边显示right_edeg页。
        
        例如: 在一个100页的页码中,当前页为第50页,使用默认配置。
        这个方法返回以下页数: 1、2、None、48、49、50、51、52、53、54、55、None、99、100
        None表示页数之间的间隔。
        
    
    @blue.route('/goodslist/<int:num>/<int:per>/')
    def goodslist(num,per):
        paginate = Goods.query.paginate(num,per)
    
        return render_template('goodslist.html', paginate=paginate)
    

    paginate对象中传递到模板中进行使用,可以使用上述属性和方法。

    三、SQLAlchemy数据查询之分页操作

    接下来以 Jinja2 宏的形式实现的分页导航,但默认这里的处理是通过get请求方式处理的,例如page=1,page=2。

    所以想要使用这里,在后续处理中,需要修改模板,还需要对数据请求方式修改为get,而不能通过path方式传参数,否则使用不了。

    • Jinja2 宏定义的形式实现的分页导航,分页模板(_macros.html)
    {% macro pagination_widget(pagination, endpoint) %}
        <ul class="pagination">
            <li{% if not pagination.has_prev %} class="disabled"{% endif %}>
                <a href="{% if pagination.has_prev %}{{ url_for(endpoint,page = pagination.page - 1, **kwargs) }}
                {% else %}#{% endif %}">&laquo;
                </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) }}">{{ p }}</a>
                        </li>
                    {% else %}
                    <li>
                        <a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>
                    </li>
                    {% endif %}
                {% else %}
                <li class="disabled">
                    <a href="#">&hellip;</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, **kwargs) }}{% else %}#{% endif %}">&raquo;</a>
            </li>
        </ul>
    {% endmacro %}
    

    pagination_widget(pagination, endpoint),需要传入pagination对象,endpoint反向解析位置(即是蓝图名.函数名)

    • index.html文件中
    {#    商品展示#}
            <ul class="goods">
                {% for goods in pagination.items %}
                    <li>
                        <p class="goodsid">商品序号: {{ goods.id }}</p>
                        <p class="name">商品名称: {{ goods.name }}</p>
                        <p class="price">商品价格: ¥{{ goods.price }}</p>
                        <p class="detail">商品描述: {{ goods.detail }}</p>
                    </li>
                {% endfor %}
            </ul>
    
    {#    宏定义形式实现的分页导航#}
            {% import "_macros.html" as macros %}
            {% if pagination %}
                <div class="pagination">
                    {{ macros.pagination_widget(pagination, 'blue.index') }}
                </div>
            {% endif %}
    

    备注: 分页导航使用的使用bootstrap中的css样式!!!

    • views.py文件中
    # 首页
    @blue.route('/')
    def index():
        # 传递的页码数量
        page = int(request.args.get('page') or 1)
        # goodslist = Goods.query.all()
    
        # 页码page,每页显示10条
        pageObj = Goods.query.paginate(page,5)
    
        return render_template('index.html', pagination=pageObj)
    

    pagination包含了所有需要的参数,包括数据,即一个pagination对象搞定所有。

    相关文章

      网友评论

          本文标题:05-Flask之数据查询(分页)

          本文链接:https://www.haomeiwen.com/subject/auwjfqtx.html