一。路由与正则。
1.当函数中需要参数,而不在路由中匹配的时候需要使用default方法:
@app.route('/index/<testreg("\d+"):nid>/',defaults={'testname':'lzx'})
2。如果要路由进入严格匹配模式,需要使用关键字段:
strict_slashes=True
3.路由匹配:
路由匹配需要导入包:
from werkzeug.routing import BaseConverter class RegexConverter(BaseConverter): """ 自定义URL匹配正则表达式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) self.regex = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值 """ #value就正则匹配出来的结果 print('value',value,type(value)) return "asdasdasd" def to_url(self, value): """ 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 """ val = super(RegexConverter, self).to_url(value) print(val) return val
在使用路由的时候,需要将器加入map:
app.url_map.converters['regex1'] = RegexConverter @app.route('/index/<regex1("\d+"):nid>',endpoint="sb",strict_slashes=) def index(nid): print("nid",nid,type(nid)) print(url_for('sb', nid='888')) # /index/666 return 'Index'
其执行周期如下:
1。导入from werkzeug.routing import BaseConverter。
2。我先要写一个类,然后继承BaseConverter,然后实现__init__, def to_python(self, value):to_url(self, value)。
3 。app.url_map.converters['任意名'] = RegexConverter。
4。 我们在路由里面@app.route('/index/<regex1("\d+"):nid>'),regex1='任意名,regex1("正则表达式")。
5。 regex1("正则表达式")匹配出来的结果,返回to_python,一定要return。
6。 当我们做反向解析的解析的时候,我们的参数,会传递给to_url,return的结果才是我们拼接到我们路由上。
二。渲染模板
当字典在模板上循环的时候,需要加上.item()
字典,支持点操作,支持【】操作,支持get操作。
除了for循环还有if循环,都与django一样。
{% for k,v in info.items() %} <tr> <td>{{k}}</td> <td>{{v.name}}</td> <td>{{v['name']}}</td> <td>{{v.get('name')}}</td> <td><a href="{{url_for('sb',nid=k)}}">查看详细</a></td> </tr> {% endfor %}
如果前端传入了字符串形式的语句,可以通过safe过滤器将其转义:
{{html|safe}} render_template('list.html',info=info,html="<h1>jsaon-gdx</h1>",html1=func1)
可以将其写成一个函数体进行传参:
from flask import Flask,Markup def func1(st,st1): return Markup(f"<h1>jsaon-gdx{st}{st1}</h1>") @app.route('/list',methods=['GET']) def list(): info=USERS return render_template('list.html',info=info,html="<h1>jsaon-gdx</h1>",html1=func1)
在前端可以传参进行传输。
其他功能,如:extends,include一样。
三。request和response
request是全局配置,需要导入模块,其中有很多的参数可以被显示:
from flask import request def login(): #提交的方法 request.method # request.args get请求提及的数据 # request.form post请求提交的数据 # request.values post和get提交的数据总和 # request.cookies 客户端所带的cookie # request.headers 请求头 # request.path 不带域名,请求路径 # request.full_path 不带域名,带参数的请求路径 # request.script_root # request.url 带域名带参数的请求路径 # request.base_url 带域名请求路径 # request.url_root 域名 # request.host_url 域名 # request.host 127.0.0.1:500 # request.files
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename))
response。
response响应的就是4剑客中响应的东西,可以使用make_response方法将返回定制化。
from flask import make_response response=make_response(render_template('index.html'))
对response的参数进行设置:
response.set_cookie('jason', 'nb') # 设置cookies response.delete_cookie('key') # 删除cookies response.headers['X-Something'] = 'A value sbwewewe' # 设置响应头
四。session
在视图函数中设置session时,需要设置密钥:
app.secret_key="askjdaksd" app.config['SESSION_COOKIE_NAME']="nb"
这个密钥就是一个乱序字符串。
SESSION_COOKIE_NAME,默认为session,是后台向前端设置ciookies的key,可以修改。
from flask import Flask,session @app.route("/") def index(): session['jason']="nb" return "ok" @app.route("/index1") def index1(): print(session['jason']) return "ok1"
取出session就是获取session的key,然后获取value,最后反解密获得session值。
如果需要将session存储到数据库中,,需要继承这个类save_session.
源码从app.session_interface中查看
五。闪现。
闪现就是一个数据存储机制,将数据暂时保存,当a用户访问到a页面之后,先到其他页面,再到b页面,需要用到a页面中的数据,就可以使用闪现。
闪现也是需要密钥的。
闪现取出一次就没有了。
但是,当处于同一视图函数的时候,可以对闪现多次取值。因为在函数内部,首先pop选中的数据,再使用这个值进行操作,但是只有操作结束之后才会清空这个值。
闪现的需要使用f模块:
from flask import Flask,flash,get_flashed_messages
flash将数据存到闪现中,category代表的是对信息进行分类。category不传默认是message。categroy_filter代表的是将依据分类进行取值(过滤)。
@app.route('/index1') def index(): #(category="message", message)) flash('超时错误',category="error") flash('普通信息',category="info") return "ssdsdsdfsd"
get_flashed_messages将数据取出来。
with_categorises将数据以键值对的形式回去(列表套字典)
@app.route('/error') def error(): data = get_flashed_messages(with_categories=True,category_filter=("error","info")) data1 = get_flashed_messages(with_categories=True, category_filter=("error", "info")) print("data1",data1) print("data",data) return "错误信息"
六。请求扩展
请求扩展和django中的中间键差不多,都参与页面访问视图函数。
1.before_request
类比django中的process_request,在请求之前绑定一个函数做一些事情。所以是先执行这个函数所绑定的函数,在访问视图函数:
@app.before_request def befor1(): print(request) print("我是请求之前1") return "123"
如果多次绑定该函数,则谁先谁先执行。
如果有一个函数有返回值,则会直接返回,不会继续执行函数。
查看源码在__call__中查看
2.after_request
在视图函数执行之后执行:
@app.after_request def after1(response): print("我是请求之后1") return response
与上一个不同,需要传入一个人response也就是,需要返回页面东西。
执行后面是先后到前
3.before_first_request
@app.before_first_request def before_first(): print("123")
这个函数只在项目不重启的情况下第一次返回值,接下来就不会执行。
4.teardown_request
@app.teardown_request def tear(e): print('teardown_request') print(e)
如论有没有异常都会执行,如果没有异常这个参数就是None,有就记录这个异常
5.errorhandler(404)
@app.errorhandler(404) def error_404(arg): print(arg) return "404错误了"
真正可以捕获的函数,如果状态时404则会捕捉错误,不会返回给用户,如果时500,则会捕捉系统错误。
6.template_global()
@app.template_global() def nb(a1, a2): return a1 + a2
这个函数可以设置全局的模板函数,直接可以在模板中用。
7.template_filter()
@app.template_filter() def db(a1, a2, a3): print(a1,a2,a3) return a1 + a2 + a3
这个过滤器与django不同,可以传多个参数,可以不用拼接成列表,而且可以直接在模板中使用。
七。中间件
在__call__中查看。
官方文档中记录了相关装配。
if __name__ == '__main__': # app.__call__ app.wsgi_app = MyMiddleware(app.wsgi_app) app.run()
其中MyMiddleware是自己写的中间键。
class MyMiddleware: def __init__(self,wsgi_app): self.wsgi_app=wsgi_app def __call__(self,environ, start_response): print("之前") res=self.wsgi_app(environ, start_response) print("之后") return res
数据执行时,会将wsgi_app进行加括号运行,这样就可以完全拆解这个周期,并且增加中间件。