filter_by() 和 filter() 的最主要的区别:
模块 | 语法 | ><(大于和小于)查询 | and_和or_查询 |
---|---|---|---|
filter_by() | 直接用属性名,比较用= | 不支持 | 不支持 |
filter() | 用类名.属性名,比较用== | 支持 | 支持 |
filter_by() 只接受键值对参数,所以 filter_by() 不支持><(大于和小于)和 and_、or_查询
filter_by()
查询 user 表里面名字等于 Tom 的:
db.session.query(User).filter_by(name='Tom').all()
查询 user 表里面名字等于 Tom 并且 年龄等于 18:
db.session.query(User).filter_by(name='Tom', age=18).all()
比如新的需求,查询 user 表里面名字等于 Tom 或者年龄等于 18 的用户,那么 filter_by() 就满足不了要求了
filter()
查询 user 表里面名字等于 Tom 的:
db.session.query(User).filter(User.name == 'Tom').all()
查询 user 表里面名字等于 Tom 并且年龄等于 18:
db.session.query(User).filter(User.name == 'Tom', User.age == 18).all()
也可以这样:
db.session.query(User).filter(User.name == 'Tom').filter(User.age == 18).all()
如果想使用 and 拼接需要用以下方式:
db.session.query(User).filter(and_(User.name == 'Tom', User.age == 18)).all()
以下的方式 and 后面的 User.age == 18 不会生效:
db.session.query(User).filter(User.name == 'Tom' and User.age == 18).all()
查询 user 表里面名字等于 Tom 的或者年龄等于 18:
db.session.query(User).filter(or_(User.name == 'Tom', User.age == 18)).all()
查询 user 表里面名字等于 Tom 的并且年龄大于 18
db.session.query(User).filter(User.name == 'Tom', User.age > 18).all()
查询 name 中包含字母 a 的所有数据(模糊查询)
db.session.query(User).filter(User.name.like('%{0}%'.format("a"))).all()
abort函数
如果在视图函数执行过程中,出现了异常错误,我们可以使用abort函数立即终止视图函数的执行。通过abort函数,可以向前端返回一个http标准中存在的错误状态码,表示出现的错误信息。
python
if email is None or password is None:
abort(400)
if User.query.filter_by(email=email).first() is not None: #filter_by 只支持键值对形式,不支持or and 查询
abort(400)
session flush在commit之前默认都会执行他。也可以手动执行它,他主要做了两件事:
1) 清理缓存。
2) 执行SQL。
flush()
导致将数据发送到数据库。commit
告诉数据库保留刚才发送的数据。
FLask之request.quest、query_string、params、body
request.quest
得到一个FormDict对象,该对象可以转化为字典,里面的内容:{'id':'1','name':'cc'},即,是url中后面的参数
request.params
也是得到FormsDict对象,转化为字典后,其内容是:
{"wzd":"111","abc":"cc","{"name":"abc"}":""}
即,其内容包含了url后的参数和值,同时也包含了body中的值,要注意的是,它把body中所以的参数作为一个key存入了。
request.body
返回一个StringIO对象,通过read方法取出的数据是body里的所有值,不管body里是不是json该方法都原样返回body里的所有内容。对本例而言是返回:{"name":"abc"}
request.query_string
它得到的是url中 ? 后面所有的值,最为一个字符串,即:wzd=111&abc=cc
name_i = request.args.get('name')
当需要获取前端页面表单传过来的id值的时候,我们就需要用request.args.get,而不能用request.form
SQLAlchemy
relationship
relationship是为了简化联合查询join等,创建的两个表之间的虚拟关系,这种关系与表的结构无关,和外键十分相似,必须建立在外键的基础上才能使用,不然会报错
python
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Father.son - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression
复杂查询
python
#查询user表里面全部的email字段以@example.com的数据
#endswith(xx):以xx结尾
User.query.filter(User.email.endswith('@example.com')).all()
get_or_404 /first_or_404
可以使用 get_or_404()
来代替 get()
,使用 first_or_404()
来代替 first()
。这样会抛出一个 404 错误,而不是返回 None
绑定多个数据库
python
SQLALCHEMY_DATABASE_URI = ''
# 绑定多个配置 #如果没有会自动加载SQLALCHEMY_DATABASE_URI
SQLALCHEMY_BINDS = {
'users': 'mysqldb://localhost/users',
'appmeta': 'sqlite:path/to/appmeta.db'
}
# 使用配置(创建删除表)
>>> db.create_all() #创建SQLALCHEMY_DATABASE_URI
>>> db.create_all(bind=['users']) # 创建SQLALCHEMY_BINDS:''users''
>>> db.create_all(bind='appmeta') # 同上
>>> db.drop_all(bind=None)
引用绑定(Binds)
python
# 当您声明模型时,您可以用 __bind_key__ 属性指定绑定(bind):
class User(db.Model):
__bind_key__ = 'users' #绑定users数据库
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
获取请求参数
request.args.get GET请求获取参数
request.form是post请求获取参数
文件上传以及展示
后端使用`files`获取值
如:``request.files.get()``
前端表单 写入参数 enctype='multipart/form-data' 当上传内容非文本(MP3。MP4。。。)时候,如图片。需要将表单的设置成enctype编码格式
filename 获得上传文件名,secure_filename函数获得安全文件名,防止客户端伪造文件
#配置上传文件大小
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
'''配置文件路径, 防止恶意读取你文件的'''
app.config['UPLOAD_FOLDER'] = '路径'
'''配置文件路径, 防止恶意读取你文件的'''
app.config['UPLOAD_FOLDER'] = 'C:/Users/Administrator/Desktop/flask/uploads/'
Cookies
获取cookies
request.cookies.get('username')
存储cookies
resp = make_response(render_template(...))
resp.set_cookie('username', 'the username')