flask基础second,配置文件,路由,模板,请求和响应对象,session使用,闪现
一、flask配置文件
全都可以在app.config里面配置
# SECRET_KEY:如果使用session,必须配置
# SESSION_COOKIE_NAME:cookie名字
# 当使用数据库连接时,由于不是内置的,所以需要配置数据库地址,端口号,也要放到配置文件中,但不是内置的参数
# flask内置session如何实现的?
-通过SECRET_KEY加密以后,当做cookie返回给浏览器
-下次发送请求,携带cookie过来,反解,再放到session中
二、路由支持正则
#1 写一个类class RegexConverter(BaseConverter):,继承BaseConverter
#2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>') 正则表达式会当作第二个参数传递到类中
from flask import Flask, views, url_for from werkzeug.routing import BaseConverter app = Flask(import_name=__name__) class RegexConverter(BaseConverter): """ 自定义URL匹配正则表达式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) self.regex = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值 """ return int(value) def to_url(self, value): """ 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 """ val = super(RegexConverter, self).to_url(value) return val # 添加到flask中 app.url_map.converters['regex'] = RegexConverter @app.route('/index/<regex("\d+"):nid>') def index(nid): print(url_for('index', nid='888')) #此时nid会传递给to_url里面的value值,自动添加给路由 return 'Index' if __name__ == '__main__': app.run()
三、模板
是jinjia2的模板语言。
# 之前学的完全一样,for,if,
# 模板语言支持函数加括号执行
# jinjia2模版已经处理xss攻击。如果要正确显示弹框,则处理方式有两种,前端和后端。
-1 模板层 要渲染的字符串|safe 比如:下的sss
-2 后端:Markup('<input type="text">')
# Markup等价django的mark_safe ,
# extends,include一模一样
#后端 from flask import Flask,render_template,session app = Flask(__name__) app.config['DEBUG'] = True def test(a,b): return a+b
def test1():
return Markup('<input type="text">')
@app.route('/index',methods=['GET','POST'],endpoint='ll') def index(): return render_template('index.html',aa='wmt',cc=test,sss='<input type="text">',dd=test1)
) #此时给函数test赋值,然后前端直接调用这个值即可 if __name__ == "__main__": app.run()
#在前端调用函数加括号,也可以传参数 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body>
{{aa}} {{ cc(1,3) }}
{%for i in ll%}
{%endfor%}
{%include%}
{% if name%}
{% else %}
{% endif %}
{{name|length}} //过滤器
{{sss|safe}}
{{dd()}} </body> </html>
四、request请求对象
可以获取前端发过来的数据的方法,
# request.method 提交的方法
# request.args get请求提及的数据
# request.form post请求提交的数据
# request.values post和get提交的数据总和
# request.cookies 客户端所带的cookie
# request.headers 请求头
# request.path 不带域名,请求路径
# # request.full_path 不带域名,带参数的请求路径
# request.url 带域名带参数的请求路径
# request.base_url 带域名请求路径
# request.url_root 域名
# request.host_url 域名
# request.host 127.0.0.1:500
# request.files
五、响应对象的方法
直接返回的三板斧:
# return "字符串" 直接返回字符串类型
# return render_template('html模板路径',**{}) 返回模板,后面可以添加其他返回数据或者函数
# return redirect('/index.html') 重定向
# return jsonify({'k1':'v1'}) 返回 json 数据
cookie相关:
aa='hello world' #aa除了可以为字符串外,还可以为其他你想设置cookie的对象,包括模板,如aa=render_template('index.html')
res=make_response(aa) #需要用make_response包装一下
res.set_cookie('xxx','lqz') #设置cookie
res.delete_cookie('key') #删除cookie
res.headers['X-Something'] = 'A value' # 往响应头中放东西
print(type(res))
from flask.wrappers import Response
return res
例子:
# response = make_response(render_template('index.html'))
# response是flask.wrappers.Response类型
# response.delete_cookie('key')
# response.set_cookie('key', 'value')
# response.headers['X-Something'] = 'A value'
# return response
# return 'hello'
六、导出项目依赖包
补充:
varchr :65535个字节的数据
-utf8:中文2个字节,varchar(300)
-utf8mb4:3个字节,varchar(300)
快速导出requestment.txt
pip3 install pipreqs
pipreqs ./ --encoding=utf-8(一般在Linux上不用加编码方式)
七、session的使用及源码
# 全局导入
# 视图函数中 session['key']=value
# 删除:session.pop('key')
# 取值:session['key']
内置session源码的类SecureCookieSessionInterface里面的方法:所以自己定义类的时候继承SessionInterface,然后重写下面两个方法。
# open_session
# save_session
from flask import Flask,session app = Flask(__name__) app.config['DEBUG'] = True #设置,使用session必须写的设置 app.secret_key='asdqewfqwfq' #配置session的规则 #app.session_interface = 类() #可以自己定义一个类,写上满足的规则 @app.route('/',methods=['GET','POST'],endpoint='ll') def index(): session['name'] = 'wmt' return 'hello' @app.route('/delete',methods=['GET','POST']) def delete(): session.pop('name') #删除session return '删除了session' @app.route('/order',methods=['GET','POST']) def order(): print(session['name']) #此时设置了session,如果没有session就访问不到 return 'order' if __name__ == "__main__": app.run(port=8080) #port=8080此时可以改访问端口
八、闪现
只能取一次,取了之后就没了
-设置一个值:flash('aaa')
-取值:get_flashed_message()
-设置:flash('lqz',category='error1')
-取值:res=get_flashed_messages(category_filter=['error1'])
-假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息
from flask import Flask,flash,get_flashed_messages app = Flask(__name__) app.config['DEBUG'] = True app.secret_key ='dewgfewgqrwh' @app.route('/',methods=['GET','POST'],endpoint='ll') def index(): flash('wmt-nb',category='error') #往某个位置放值,一直放着,只要取了一次,就没了,这里的category是分类的意思。取值时可以直接取分类就可以得出闪现的值 return 'hello' @app.route('/order',methods=['GET','POST']) def order(): res = get_flashed_messages(category_filter=['error']) #这里就是取得分类,而不用直接取'wmt-nb'
print(res) #从某个位置出来,只要这里取了一次,下次就没有这个闪现值了 return 'ccccc' if __name__ == "__main__": app.run()
九、请求扩展
类似于django的中间件,请求来与请求走的相关操作
@app.before_request
请求来就会触发这个方法,类似于django的process_request,如果有多个,顺序是从上往下。比如下面的例子就是先打印222,再打印111.
@app.before_request def before(*args,**kwargs):
print(222) if request.path=='/login': return None else: name=session.get('user') if not name: return redirect('/login') else: return None
@app.before_request
def before(*args,**kwargs):
print(111)
if request.path=='/login':
return None
else:
name=session.get('user')
if not name:
return redirect('/login')
else:
return None
@app.after_request
请求走了就会触发,类似于django的process_response,如果有多个,顺序是从下往上执行
@app.after_request def after(response):return response
@app.before_first_request
before_first_request 项目启动起来第一次会走,以后都不会走了,也可以配多个(项目启动初始化的一些操作)
@app.before_first_request def first(): print('项目启动,我只执行一次,下次就看不到我了')
@app.teardown_request # 用来记录出错日志,每个视图函数只要执行,就会自动执行此方法。此方法需要把调试模式关了
@app.teardown_request def ter(e): print(e) print('我是teardown_request ')
errorhandler绑定错误的状态码,只要访问项目出错后,出错的状态码只要与设定的状态码匹配,那么就会自动执行此方法。返回对应界面
@app.errorhandler(404) def error_404(arg): return render_template('error.html',message='404错误')
全局标签:在项目任何一个模板都可以使用,且不用在后端视图传值
@app.template_global() def sb(a1, a2): return a1 + a2
#在模板中:{{ sb(参数1,参数2) }}
全局过滤器:同上,在项目任何模板都可以使用,且不用在后端视图传值
@app.template_filter() def db(a1, a2, a3): return a1 + a2 + a3
#在模板中{{ 1|db(2,3)}} 就是{{参数1|db(参数2,参数3)}}
注意:
before_request和after_request,
注意有多个的情况,执行顺序
before_request请求拦截后(也就是有return值),response所有都执行