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__ 小于等于
import random
from operator import or_, and_
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///flaskmodel.sqlite"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app) class Student(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(32), unique=True)
score = db.Column(db.Integer, default=60)
def save(self): # 类方法。对数据进行保存提交
db.session.add(self)
db.session.commit() # 数据库初始化,新建一个数据库
@app.route("/init/")
def init():
db.create_all() # 新建数据库
return "初始化成功"
# 新建一个学生表,在内加入学生信息
@app.route("/addstudent/")
def add_student():
student = Student(name="小明%d" % random.randrange(10000), score=random.randrange(100))
student.save() # 调用save()类方法,对要添加的数据进行添加提交
return "添加成功" @app.route("/students/")
def students():
# 获取成绩在 80分以上的学生信息
student_list = Student.query.filter(Student.score > 80).all()
student_list = Student.query.filter(Student.score.__gt__(80)).all() # 获取成绩在 60分以下的学生信息
student_list = Student.query.filter(Student.score < 60).all()
student_list = Student.query.filter(Student.score.__lt__(60)).all() # 获取成绩是 [60、81、100、200]列表内的学生信息
student_list = Student.query.filter(Student.score.in_([60, 81, 100, 200])).all() # 获取成绩在 60分以上、80分一下的学生信息。
# filter之后对象类型是BaseQuery,可以链式调用:Student.query.filter(xxx).filter().filter().filter()
student_list = Student.query.filter(Student.score > 60).filter(Student.score < 80).all() # filter_by():通常级联查询,条件是确切的=那种。条件 改成 属性=值
student_list = Student.query.filter_by(score = 80).all() # offset():越过三条数据取3条数据的 学生数据结果
student_list = Student.query.offset(3).limit(3).all() # 通过成绩从高到底排序,order_by(text("-score"))
student_list = Student.query.order_by(text("-score")).all() # 通过order_by对成绩排序,越过前三条数据后offset(3),取四条学生信息数据limit(4)
# order_by必须放在最前面。limit和offset无顺序,实际上都是先offset再limit
student_list = Student.query.order_by("score").limit(4).offset(3).all() # BaseQuery是可迭代元素,可以被for..in迭代出元素。all只是将格式转换为了列表。
student_list = Student.query.order_by("score") # 获取学生数据的第一个元素,结果不再是复数。不可迭代。结果的类型是一个Student对象
student = Student.query.first()
return render_template("student_list1.html", student_list=student_list) # 原生分页。可以从客户端接受参数,参数是页码,每一个三条数据
page = request.args.get("page", 1, type=int) # 获取get请求数据:参数是page、默认值是1、类型是:int
student_list = Student.query.offset(3*(page-1)).limit(3).all()
return render_template("student_list1.html", student_list=student_list) # 对获取的数据进行分页
pagination = Student.query.paginate()
return render_template("student_list1.html", pagination=pagination) if __name__ == '__main__':
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))
# 查询指定范围内的数据。and_ 方法
@app.route("/students2/")
def students2():
student_list = Student.query.filter(and_(Student.score.__gt__(60), Student.score.__lt__(90)))
return render_template("student_list2.html", student_list=student_list) # 查询后 删除数据
@app.route("/dropfirst/")
def drop_first():
student = Student.query.order_by(text("-score")).first()
print(student.score)
db.session.delete(student)
db.session.commit()
return "" # 查询后,修改数据值
@app.route("/updatescore/")
def update_score():
student = Student.query.order_by(text("score")).first()
print(student.score, student.id)
student.score = 100
db.session.add(student)
db.session.commit()
return "完成" if __name__ == '__main__':
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(page,per_page, False(是否抛异常))
- page: 当前的⻚页码
- per_page: 每⻚页的条数
- error_out: 当查询出错时是否报错
@bp.route('/students/')
def student_list():
"""
/students/?page=2
"""
page = int(request.args.get('page', 1))
per_page = 2 # 每页显示2条数据
students = Student.query.paginate(page=page, per_page=per_page) return render_template('students.html', students=students)
- 属性
page:当前⻚页码 pages:总⻚页数 total:总条数
prev_num:上⼀⻚页的⻚页码 next_num: 下⼀⻚页的⻚页码
has_prev: 是否有上一⻚页 has_next: 是否有下一⻚页
items: 当前⻚页的数据 per_page: 每⻚页的条数,默认为20条
<div>
<a href="{{ url_for('blue.student_list') }}">首页</a> {% if students.has_prev %} 是否有上一页
<a href="{{ url_for('blue.student_list', page=students.prev_num) }}">上一页</a>
{% endif %} 当前{{ students.page }}页,共{{ students.pages }}页,总共{{ students.total }}条 {% if students.has_next %} 是否有下一页
<a href="{{ url_for('blue.student_list', page=students.next_num) }}">下一页</a>
{% endif %} <a href="{{ url_for('blue.student_list', page=students.pages) }}">尾页</a>
</div>
- 方法
- iter_pages: 返回一个迭代器。在分页导航条上显示的页码列表。显示不完全时返回NOne
- prev: 上⼀页的分页对象
- next: 下一⻚的分页对象
<div>
{% for page in students.iter_pages() %}
{% if page %}
{% if page == students.page %}
{{ page }}
{% else %}
<a href="{{ url_for('blue.student_list', page=page) }}">{{ page }}</a>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
</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 %}">«
</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="#">…</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 %}">»</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 自定义模板过滤器
@bp.app_template_filter('mycut')
def mycut(x):
return x if len(x) < 6 else x[:5] + '...'
"""
使用
<p>{{ 'hello' | mycut }}</p>
"""
拾遗
# 自定义上下文处理器。context_processor(模板的全局变量)
import time @app.context_processor
def client_ip():
return dict(remote_ip=request.remote_addr) @app.context_processor
def get_current_time():
def get_time(fmt="%b %d, %Y - %H:%M:%S"):
return time.strftime(fmt)
return dict(current_time=get_time) # 使用:在任意模板页面都可以是使用 current_time 这个函数
<p>Current Time is: {{ current_time() }}</p>
<p>Current Day is: {{ current_time("%Y-%m-%d") }}</p> # ————————————————————————————————————————————————————————————#
# 自定义模板过滤器。template_filter
@bp.app_template_filter('mycut')
def mycut(x):
return x if len(x) < 6 else x[:5] + '...' # 使用
<p>{{ 'hello' | mycut }}</p>
flask 之(三) --- 筛选|分页|过滤的更多相关文章
- vuejs实现本地数据的筛选分页
今天项目需要一份根据本地数据的筛选分页功能,好吧,本来以为很简单,网上搜了搜全是ajax获取的数据,这不符合要求啊,修改起来太费力气,还不如我自己去写,不多说直接上代码 效果图: 项目需要:点击左侧进 ...
- Flask学习之九 分页
英文博客地址:http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-ix-pagination 中文翻译地址:http:// ...
- Flask备注三(Context)
Flask备注三(Context) Flask支持不同的应用场景下,对应不同的local context(本地上下文环境),用来提供当前环境下的资源.lcoal context和全局变量以及局部变量最 ...
- Asp.Net中的三种分页方式
Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...
- Fiddler基础使用三之请求过滤
在我们抓包的时候如果不设置过滤,那么所有操作中的请求都会被捕获下来,如果我们只想查看指定或者某些请求信息,那么太多的session会给我们造成困扰,增加查找难度.所以我们需要设置过滤区域.fiddle ...
- hbase 分页过滤(新老API的差别)
在hbase2.0以前分页过滤必须以上一次的最后一行+空字节数组作为下一次的起始行, 因为scan扫描的时候是包含起始行的,为了既能准确定位起始行,但又不重复把上一次的最末一行加入下一页, 所以,权威 ...
- Asp.net Core C#进行筛选、过滤、使用PredicateBuilder进行动态拼接lamdba表达式树并用作条件精准查询,模糊查询
在asp.net core.asp.net 中做where条件过滤筛选的时候写的长而繁琐不利于维护,用PredicateBuilder进行筛选.过滤.LInq配合Ef.core进行动态拼接lamdba ...
- DjangoRestFramework框架三种分页功能的实现 - 在DjangoStarter项目模板中封装
前言 继续Django后端开发系列文章.刚好遇到一个分页的需求,就记录一下. Django作为一个"全家桶"型的框架,本身啥都有,分页组件也是有的,但默认的分页组件没有对API开发 ...
- Flask学习之旅--分页功能:分别使用 flask--pagination 和分页插件 layPage
一.前言 现在开发一个网站,分页是一个很常见的功能了,尤其是当数据达到一定量的时候,如果都显示在页面上,会造成页面过长而影响用户体验,除此之外,还可能出现加载过慢等问题.因此,分页就很有必要了. 分页 ...
随机推荐
- linux系统常用命令(一)
管理 在UNIX/linux系统中,一切皆为文件:若非文件,则为进程.首先认识文件系统: linux文件系统 /var - 经常变化的(variable)文件,诸如日志或数据库等 /usr - 包含绝 ...
- Ubuntu 16.04安装docker详细步骤
1. 卸载之前的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io 2. 更新apt包 sudo apt-get upda ...
- [Git] How to revert one file changes from one commit
Many times we might changed one file which we don't intent to do... but it was too late, until we fo ...
- 【Python网络】HTTP
HTTP概述 HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则. HTTP就是一个通信规则,通信规则规定 ...
- golang配置oci8所遇到问题解决
新建文件夹 mingw 将 MinGW.zip 解压到mingw目录下,进入mingw\lib目录下 新建文件夹pkg-config 执行命令 go get github.com/wendal/go- ...
- BZOJ1968: [Ahoi2005]COMMON 约数研究 线性筛
按照积性函数的定义筛一下这个积性函数即可. #include <cstdio> #include <algorithm> #define N 1000004 #define s ...
- 51 Nod 1101 换零钱(动态规划好题)
1101 换零钱 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 N元钱换为零钱,有多少不同的换法?币值包括1 2 5分,1 2 5角,1 2 5 ...
- HZOJ 20190719 那一天她离我而去(图论最小环)
这题算是这场考试里最水的一道题了吧,就是求个最小环,但之前没练过,就在考场上yy出了最短路+次短路的傻逼解法,首先是不会求次短路,其次是这显然不对呀,自己随便想想就可以反驳这种解法. 正解比较神,但是 ...
- 灰度图像--图像分割 Marr-Hildreth算子(LoG算子)
学习DIP第49天 转载请标明本文出处:*http://blog.csdn.net/tonyshengtan *,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发: https:/ ...
- 线性素数筛(欧拉筛)(超级好的MuBan)
Problem:找出小于等于n的所有素数的个数. #include <bits/stdc++.h> using namespace std; const int maxn = 1e6; i ...