zoukankan      html  css  js  c++  java
  • flask 之(三) --- 筛选|分页|过滤

    筛选

    查询数据筛选语法:类名.query.筛选符 

      .all( ):获取结果集;.count( ):获取查询到的对象数量

      类名.query.filter(类名.属性.运算符('xxx')).all()

      类名.query.filter(类名.属性 数学运算符 值).all()

    筛选符:

      filter_by():根据什么过滤,通常用在级连关系查询上,属性=值。不常用;     filter():         查询获取数据

      offset(): 偏移,偏移前几条取数据; limit(): 限制,限制取多少条数据;   order_by(): 根据什么字段排序;  

      get():  根据主键获取数据;    first():  取第一个元素;        paginate():   分页

    • 数学运算符:

       contains 包含,模糊查询; startswith 以什么开始; endswith  以什么结束;

       in_  在什么范围中;     like  包含,模糊查询; __gt__  大于 

       __ge__  大于等于;     __lt__  小于;     __le__  小于等于

     1 import random
     2 from operator import or_, and_
     3 from flask import Flask, render_template, request, redirect, url_for
     4 from flask_sqlalchemy import SQLAlchemy
     5 from sqlalchemy import text
     6 
     7 app = Flask(__name__)
     8 app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///flaskmodel.sqlite"
     9 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    10 db = SQLAlchemy(app)
    11 
    12 
    13 class Student(db.Model):
    14     id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    15     name = db.Column(db.String(32), unique=True)
    16     score = db.Column(db.Integer, default=60)
    17     def save(self):     # 类方法。对数据进行保存提交
    18         db.session.add(self)
    19         db.session.commit()
    20 
    21 # 数据库初始化,新建一个数据库
    22 @app.route("/init/")
    23 def init():
    24     db.create_all() # 新建数据库
    25     return "初始化成功"
    26 # 新建一个学生表,在内加入学生信息
    27 @app.route("/addstudent/")
    28 def add_student():
    29     student = Student(name="小明%d" % random.randrange(10000), score=random.randrange(100))
    30     student.save()      # 调用save()类方法,对要添加的数据进行添加提交
    31     return "添加成功"
    32 
    33 
    34 @app.route("/students/")
    35 def students():
    36     # 获取成绩在 80分以上的学生信息
    37     student_list = Student.query.filter(Student.score > 80).all()
    38     student_list = Student.query.filter(Student.score.__gt__(80)).all()
    39 
    40     # 获取成绩在 60分以下的学生信息
    41     student_list = Student.query.filter(Student.score < 60).all()
    42     student_list = Student.query.filter(Student.score.__lt__(60)).all()
    43 
    44     # 获取成绩是 [60、81、100、200]列表内的学生信息
    45     student_list = Student.query.filter(Student.score.in_([60, 81, 100, 200])).all()
    46 
    47     # 获取成绩在 60分以上、80分一下的学生信息。
    48     # filter之后对象类型是BaseQuery,可以链式调用:Student.query.filter(xxx).filter().filter().filter()
    49     student_list = Student.query.filter(Student.score > 60).filter(Student.score < 80).all()
    50 
    51 
    52     # filter_by():通常级联查询,条件是确切的=那种。条件 改成 属性=值
    53     student_list = Student.query.filter_by(score = 80).all()
    54 
    55     # offset():越过三条数据取3条数据的 学生数据结果
    56     student_list = Student.query.offset(3).limit(3).all()
    57 
    58     # 通过成绩从高到底排序,order_by(text("-score"))
    59     student_list = Student.query.order_by(text("-score")).all()
    60 
    61     # 通过order_by对成绩排序,越过前三条数据后offset(3),取四条学生信息数据limit(4)
    62     # order_by必须放在最前面。limit和offset无顺序,实际上都是先offset再limit
    63     student_list = Student.query.order_by("score").limit(4).offset(3).all()
    64 
    65 
    66     # BaseQuery是可迭代元素,可以被for..in迭代出元素。all只是将格式转换为了列表
    67     student_list = Student.query.order_by("score")
    68 
    69     # 获取学生数据的第一个元素,结果不再是复数。不可迭代。结果的类型是一个Student对象
    70     student = Student.query.first()
    71     return render_template("student_list1.html", student_list=student_list)
    72 
    73 
    74     # 原生分页。可以从客户端接受参数,参数是页码,每一个三条数据
    75     page = request.args.get("page", 1, type=int)  # 获取get请求数据:参数是page、默认值是1、类型是:int
    76     student_list = Student.query.offset(3*(page-1)).limit(3).all()
    77     return render_template("student_list1.html", student_list=student_list)
    78 
    79     # 对获取的数据进行分页
    80     pagination = Student.query.paginate()
    81     return render_template("student_list1.html", pagination=pagination)
    82 
    83 
    84 if __name__ == '__main__':
    85         app.run()    
    • 逻辑运算符: 

      与and_  或or_  非not_

      filter(and_(条件),条件...)  filter(or_(条件),条件...)  filter(not_(条件),条件...)

    # 与:and_   filter(and_(条件))
    huochelist = kaihuoche.query.filter(and_(kaihuoche.id == 1,kaihuoche.name == 'lc'))
    
    # 或:or_    filter(or_(条件))
    huochelist = kaihuoche.query.filter(or_(kaihuoche.id == 1,kaihuoche.name =='lc'))
    
    # 非:not_   filter(not_(条件))  注意条件只能有一个
    huochelist = kaihuoche.query.filter(not_(kaihuoche.id == 1))
     1 # 查询指定范围内的数据。and_ 方法
     2 @app.route("/students2/")
     3 def students2():
     4     student_list = Student.query.filter(and_(Student.score.__gt__(60), Student.score.__lt__(90)))
     5     return render_template("student_list2.html", student_list=student_list)
     6 
     7 # 查询后 删除数据
     8 @app.route("/dropfirst/")
     9 def drop_first():
    10     student = Student.query.order_by(text("-score")).first()
    11     print(student.score)
    12     db.session.delete(student)
    13     db.session.commit()
    14     return "88"
    15 
    16 # 查询后,修改数据值
    17 @app.route("/updatescore/")
    18 def update_score():
    19     student = Student.query.order_by(text("score")).first()
    20     print(student.score, student.id)
    21     student.score = 100
    22     db.session.add(student)
    23     db.session.commit()
    24     return "完成"
    25 
    26 if __name__ == '__main__':
    27     app.run()

    分页

      分页器:paginate。分页查询,需要想要的页码,每一页显示多少数据

      分页对象:分页器(Pagination)返回的对象。包含了所有的分⻚页信息。

      封装实现:persons = Person.query.paginate(page_num, per_page, False).items

      原生实现:persons = Person.query.offset((page_num - 1) * per_page).limit(per_page) 

           select * from users offset 0 limit 20   ;select * from users offset 20 limit 40

    • 使用:pagination(pageper_page, False(是否抛异常))
      •  page:       当前的⻚页码
      •  per_page: 每⻚页的条数
      •  error_out: 当查询出错时是否报错
     1 @bp.route('/students/')
     2 def student_list():
     3     """
     4     /students/?page=2
     5     """
     6     page = int(request.args.get('page', 1))
     7     per_page = 2   # 每页显示2条数据
     8     students = Student.query.paginate(page=page, per_page=per_page)
     9 
    10     return render_template('students.html', students=students)
    • 属性

        page:当前⻚页码      pages:总⻚页数      total:总条数

        prev_num:上⼀⻚页的⻚页码   next_num:   下⼀⻚页的⻚页码

        has_prev: 是否有上一⻚页      has_next:     是否有下一⻚页

        items:      当前⻚页的数据      per_page:    每⻚页的条数,默认为20条

     1 <div>
     2     <a href="{{ url_for('blue.student_list') }}">首页</a>
     3 
     4     {% if students.has_prev %}   是否有上一页
     5         <a href="{{ url_for('blue.student_list', page=students.prev_num) }}">上一页</a>
     6     {% endif %}
     7 
     8     当前{{ students.page }}页,共{{ students.pages }}页,总共{{ students.total }}条
     9     
    10     {% if students.has_next %}  是否有下一页
    11         <a href="{{ url_for('blue.student_list', page=students.next_num) }}">下一页</a>
    12     {% endif %}
    13 
    14     <a href="{{ url_for('blue.student_list', page=students.pages) }}">尾页</a>
    15 </div>
    • 方法
      • iter_pages:  返回一个迭代器。在分页导航条上显示的页码列表。显示不完全时返回NOne
      • prev:          上⼀页的分页对象
      • next:              下一⻚的分页对象
     1 <div>
     2     {% for page in students.iter_pages() %}
     3         {% if page %}
     4             {% if page == students.page %}
     5                 {{ page }}
     6             {% else %}
     7                 <a href="{{ url_for('blue.student_list', page=page) }}">{{ page }}</a>
     8             {% endif %}
     9         {% else %}
    10             ...
    11         {% endif %}
    12     {% endfor %}
    13 </div>
    • 分页宏定义
    {# 分页显示的宏 #}
    {% 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 %}

    过滤

     过滤器: 

       default:默认值    capitalize:首字母大写    lower:全小写    upper:全大写    

       trim:去除空格    reverse:反转    format:格式化输出    safe:关闭转义(已审查,没有安全隐患)    

       striptags:将值中标签去掉    round:四舍五入(截取)    abs:绝对值    first:第一个元素    

       last:最后一个元素    length:列表长度    sum:列表求和    sort:列表排序(升序)      join:合并字符串

    • 模版文件中
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    
    语法:
        {{ 变量 | 过滤器 | 过滤器 }}
    例子:
        {# 当变量未定义时,显示默认字符串,可以缩写为d #}
        <p>{{ name | default('No name') }}</p>
     
        {# 单词首字母大写 #}
        <p>{{ 'hello' | capitalize }}</p>
     
        {# 单词全小写 #}
        <p>{{ 'XML' | lower }}</p>
     
        {# 去除字符串前后的空白字符 #}
        <p>{{ 'hello' | trim }}</p>
     
        {# 字符串反转,返回"olleh" #}
        <p>{{ 'hello' | reverse }}</p>
     
        {# 格式化输出,返回"Number is 2" #}
        <p>{{ '%s is %d' | format("Number", 2) }}</p>
     
        {# 关闭HTML自动转义 #}
        <p>{{ '<em>name</em>' | safe }}</p>
        
        {# 四舍五入取整,返回13.0 #}
        <p>{{ 12.8888 | round }}</p>
     
        {# 向下截取到小数点后2位,返回12.88 #}
        <p>{{ 12.8888 | round(2, 'floor') }}</p>
     
        {# 绝对值,返回12 #}
        <p>{{ -12 | abs }}</p>
    
        {# 取第一个元素 #}
        <p>{{ [1,2,3,4,5] | first }}</p>
     
        {# 取最后一个元素 #}
        <p>{{ [1,2,3,4,5] | last }}</p>
     
        {# 返回列表长度,可以写为count #}
        <p>{{ [1,2,3,4,5] | length }}</p>
     
        {# 列表求和 #}
        <p>{{ [1,2,3,4,5] | sum }}</p>
     
        {# 列表排序,默认为升序 #}
        <p>{{ [3,2,1,5,4] | sort }}</p>
     
        {# 合并为字符串,返回"1 | 2 | 3 | 4 | 5" #}
        <p>{{ [1,2,3,4,5] | join(' | ') }}</p>
    
    </body>
    </html>
    • template_filter 自定义模板过滤器
    1 @bp.app_template_filter('mycut')
    2 def mycut(x):
    3     return x if len(x) < 6 else x[:5] + '...'
    4 """    
    5 使用
    6 <p>{{ 'hello' | mycut }}</p>
    7 """


     拾遗

     1 # 自定义上下文处理器。context_processor(模板的全局变量)
     2 import time
     3 
     4 @app.context_processor
     5 def client_ip():
     6   return dict(remote_ip=request.remote_addr)
     7 
     8 @app.context_processor
     9 def get_current_time():
    10   def get_time(fmt="%b %d, %Y - %H:%M:%S"):
    11     return time.strftime(fmt)
    12   return dict(current_time=get_time)
    13 
    14 # 使用:在任意模板页面都可以是使用 current_time 这个函数
    15 <p>Current Time is: {{ current_time() }}</p>
    16 <p>Current Day is: {{ current_time("%Y-%m-%d") }}</p> 
    17   
    18   
    19 # ————————————————————————————————————————————————————————————#
    20 # 自定义模板过滤器。template_filter 
    21 @bp.app_template_filter('mycut')
    22 def mycut(x):
    23     return x if len(x) < 6 else x[:5] + '...'
    24   
    25 # 使用  
    26 <p>{{ 'hello' | mycut }}</p>
    生如逆旅 一苇以航
  • 相关阅读:
    (转)asp.net页面出错时的处理方法
    Angular.js学习笔记 (二) H.U.C
    一套常用的css初始化样式 H.U.C
    hexo工具介绍及使用方法 H.U.C
    Angular.js学习笔记 (一) H.U.C
    Nhibernate 对view 查询的几种方法
    如何做类似google的Textbox的AutoComplete增强版,可以显示多列
    POS 打印机编程控制
    (转) 商品损耗控制
    win 2008 IIS 7 安装 PHPMYAdmin
  • 原文地址:https://www.cnblogs.com/TMMM/p/11469504.html
Copyright © 2011-2022 走看看