自定义路由正则匹配:# 添加到flask中# 我们要用自定义的路由,用正则的话# 1导入from werkzeug.routing import BaseConverter# 2我先要写一个类,然后继承BaseConverter,然后实现进行初始化,to_python(self, value),to_url(self, value)# 3 app.url_map.converters['regex1'] = RegexConverter# 4 我们在路由里面@app.route('/index/<regex1("\d+"):nid>'),regex1='谁便,regex1("正则表达式")# 5 regex1("正则表达式")匹配出来的结果,返回to_python,一定要return# 6 当我们做反向解析的解析的时候,我们的参数,会传递给to_url,return的结果才是我们拼接到我们路由上
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):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
"""
# 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) #666
return val
app.url_map.converters['regex1'] = RegexConverter
@app.route('/index/<regex1("\d+"):nid>', endpoint="sb")
def index(nid):
print("nid", nid, type(nid))
print(url_for('sb', nid='666')) # /index/666
return 'Index'
if __name__ == '__main__':
app.run()
模板语法:
'''jinjia2模板语言 -前端:支持函数加括号并且传参 {{ func(1,2,3) | safe}} -其他的用法完全同DTL -后台:视图函数用 aa=Markup(a) -jinjia2有没有处理xss攻击? - html中的特殊符号'''
from flask import Flask, url_for, render_template, Markup
app = Flask(__name__)
@app.route('/')
def index():
# def func(a, b, c):
# return 'sb', a + b + c
a = "<input type='text' value='sb'>"
a = Markup(a) # 后台转义标签
return render_template('index.html', func=a) # 函数作为值传参,前端函数还可以携带参数
if __name__ == '__main__':
app.run(port=8000)
# 这里run本质上就是run_simple
请求响应:
from flask import Flask, render_template, request, make_response
app = Flask(__name__)
app.debug = True
@app.route('/', methods=['GET', 'POST'])
def index():
# print(request.args.get('id')) # get请求取值
# print(request.form.get('name')) # post请求取值
# request.values post和get提交的数据总和
# request.cookies 客户端所带的cookie
# request.headers 请求头
# request.script_root
# request.url 带域名带参数的请求路径
# request.base_url 带域名请求路径
# request.url_root 域名
# request.host_url 域名
# request.host 127.0.0.1:500
# request.files
# request.files 文件
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename)) # 存入文件
print(request.method) # 请求方法
print(request.path) # 请求路径(根路径)
print(request.full_path) # 请求路径携带参数路径(全路径)
obj = make_response('你大爷的!') # 只是把值进行封装
obj.set_cookie('key', '1456sxxxxxxxsss') # 往前端传送设置cookie键值对
obj.delete_cookie('key') # 删除掉cookie
obj.headers['xxxx'] = 'yyyyyyyy' # 响应头
return obj
if __name__ == '__main__':
app.run(port=8000)
# 这里run本质上就是run_simple
路由的其他参数和使用:
# app.add_url_rule("/", view_func=UserView.as_view(name="user"))
# rule, URL规则
# view_func, 视图函数名称
# 为函数提供参数
# endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
# methods = None, 允许的请求方式,如:["GET", "POST"]
# defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}
# #对URL最后的 / 符号是否严格要求
# strict_slashes = None
# '''
# @app.route('/index', strict_slashes=False)
# #访问http://www.xx.com/index/ 或http://www.xx.com/index均可
# @app.route('/index', strict_slashes=True)
# #仅访问http://www.xx.com/index
# '''
# #重定向到指定地址
# redirect_to = None,
from flask import Flask, redirect, render_template, jsonify, views
app = Flask(__name__)
# strict_slashes,该参数是用来设置,我们的路由是否为严格模式,False是非严格模式,True严格,默认是严格
@app.route("/index", strict_slashes=True, redirect_to="/login")
def index():
return "ok"
@app.route("/login")
def login():
return "sb"
@app.route("/detail/<int:nid>")
def detail(nid):
print(nid)
return "ok"
if __name__ == '__main__':
app.run()
session的使用
"""session: -使用必须先设置一下秘钥:app.secret_key = 'nimaipaffsf' -session['name']='kevin'存值放前端,取值 session['name']) # 取值的时候,把前端cookie通过解密,获取得到 -源码流程: -save_session -响应的时候,把session中的值解密序列化放到了cookie中,返回浏览器 -open_session -请求来了,从cookie中取出来,反解,生成session对象,以后在视图函数中直接用session就可以"""
from flask import Flask, session
app = Flask(__name__)
app.secret_key = '你打卖批'
app.debug = True
# app.config['SESSION_COOKIE_NAME'] = 'dsb'
@app.route('/', methods=['GET', 'POST'])
def index():
session['name'] = 'kevin'
return 'index'
@app.route('/test', methods=['GET', 'POST'])
def test():
print(session['name']) # 取值的时候,把前端cookie通过解密,获取得到
return 'test'
if __name__ == '__main__':
app.run()
闪现
"""
什么是闪现:
a产生信息,传给c页面
但是用户访问a页面以后,不是直接跳转到c,而是到b,或者是其它页面,但是用户访问c页面的时候,a给我的信息能拿到
"""
from flask import Flask, flash, get_flashed_messages, request
app = Flask(__name__)
app.secret_key = 'adsfsfsdgfsg'
# 1.如果要用flash就必须设置app.secret_key = 'adsfsfsdgfsg'
# 2.闪现设置好的值,只能去一次,如果再次刷新页面就取不到
# 3.我们可以通过 flash('普通信息',category="info"),对信息做分类
# 4.我们设置闪现,category_filter=("error",)进行分类信息的过滤,筛选
# 5.with_categories=True,是将显示信息把分类显示
@app.route('/index')
def index():
flash('超时信息', category='error')
flash('普通信息', category='info')
return 'sffsfsfffsffsdfds'
@app.route('/error1')
def error1():
return '错误1'
@app.route('/error2')
def error2():
data = get_flashed_messages(with_categories=True,category_filter=('error', 'info'))
data1 = get_flashed_messages(with_categories=True, category_filter=('error', 'info'))
print(data, data1)
print(data, data1)
return '错误2'
if __name__ == '__main__':
app.run()
before_request和after_request
from flask import Flask, request, render_template
app = Flask(__name__)
'''@app.before_request在请求进入视图函数之前执行'''
# @app.before_request
# def befor1():
# print(request)
# print("我是请求之前1")
# return "123"
#
#
# @app.before_request
# def befor2():
# print("我是请求之前2")
'''@app.after_request:在视图函数响应之后执行,但是必须接受参数response,并返回它'''
# @app.after_request
# def after1(response):
# print("我是请求之后1")
# return response
#
# @app.after_request
# def after2(response):
# print("我是请求之后2")
# return response
"""before_first_request:只执行一次,第一次请求之前,第二次请求不执行"""
@app.before_first_request
def before_first():
print("123")
# 如论有没有异常都会执行,如果没有异常这个参数就是None,有就记录这个异常
# @app.teardown_request
# def tear(e):
# print('teardown_request')
# print(e)
# 捕获异常,如果出现异常,而且状态就是@app.errorhandler(404),
# @app.errorhandler(404)
# def error_404(arg):
# print(arg)
# return "404错误了"
# @app.errorhandler(500)
# def error(arg):
# print(arg)
# return "500错误了"
"""@app.template_global():设置全局函数,可以传进前端{{ sb(1,2)}}"""
# @app.template_global()
# def sb(a1, a2):
# return a1 + a2
# 也是一种函数传参方式{{1|db(2,3)}}
# @app.template_filter()
# def db(a1, a2, a3):
# print(a1, a2, a3)
# return a1 + a2 + a3
@app.route('/index')
def index():
print("我是真的视图")
return render_template("index.html")
if __name__ == '__main__':
# app.__call__
app.run()
中间件:
from flask import Flask
app = Flask(__name__)
app.secret_key = 'jhfksfhsdfsd'
app.debug = True
"""
中间件:跟django中的中间件不一样
-flask中一旦请求到来,要执行app()---->执行的是app.__call__,整个flask的入口(call在实例化对象中会走,对象的属性存在call方法里)
"""
class MyMiddleware:
def __init__(self, my_wsgi_app):
self.wsgi_app = my_wsgi_app # 进行初始化
def __call__(self, environ, start_response):
print("之前")
obj = self.wsgi_app(environ, start_response)
print("之后")
return obj
@app.route('/index')
def index():
return "ok"
if __name__ == '__main__':
# app.__call__
app.wsgi_app = MyMiddleware(app.wsgi_app)
app.run()
# 请求来了,执行__call__本质是执行self.wsgi_app(environ, start_response),
# MyMiddleware(app.wsgi_app)app.wsgi_app本质就是flask最终执行的方法,然后传参进去,走call方法,把执行后的结果返回出来