python Flask web框架
目录:
--> Flask
--> 配置文件
--> 配置文件解析
--> 配置文件导入
--> 路由
--> 路由参数
--> 常用路由匹配
--> 请求相关 & 响应
--> request 参数
--> response 参数
--> 打包模板和参数
--> 模板 jinja2
--> 模板导入/继承
--> 前段/后端 安全渲染
--> 前段自定义函数 macro
--> 后端自定义前段函数
--> @app.template_global()
--> @app.template_filter()
--> 请求扩展
--> @app.before_first_request
--> @app.before_request
--> @app.after_request
--> 错误页面自定制
--> 闪现
--> 蓝图
--> 中间件
--> 信号
--> 上下文管理
--> threading.local
--> 请求上下文(requestContext)
--> request
--> session
--> 应用上下文:AppContext
--> app(current_app)
--> g
--> 实现细节
--> 利用threading.local 的线程 唯一ID标识符
--> requestcontext对象通过localstack添加到Local 栈中
--> 导入request(session、current_app、g)是localproxy -> 偏函数 ->Localstack -> Local
--> requestcontext的auto_pop -> localstaack.pop ->local中移除
--> 多app应用
--> 技术点:LocalProxy、chain,偏函数
--> 中间件/信号 执行顺序
falsk 配置文件解析
- {
- 'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
- 'TESTING': False, 是否开启测试模式
- 'PROPAGATE_EXCEPTIONS': None,
- 'PRESERVE_CONTEXT_ON_EXCEPTION': None,
- 'SECRET_KEY': None,
- 'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
- 'USE_X_SENDFILE': False,
- 'LOGGER_NAME': None,
- 'LOGGER_HANDLER_POLICY': 'always',
- 'SERVER_NAME': None,
- 'APPLICATION_ROOT': None,
- 'SESSION_COOKIE_NAME': 'session',
- 'SESSION_COOKIE_DOMAIN': None,
- 'SESSION_COOKIE_PATH': None,
- 'SESSION_COOKIE_HTTPONLY': True,
- 'SESSION_COOKIE_SECURE': False,
- 'SESSION_REFRESH_EACH_REQUEST': True,
- 'MAX_CONTENT_LENGTH': None,
- 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
- 'TRAP_BAD_REQUEST_ERRORS': False,
- 'TRAP_HTTP_EXCEPTIONS': False,
- 'EXPLAIN_TEMPLATE_LOADING': False,
- 'PREFERRED_URL_SCHEME': 'http',
- 'JSON_AS_ASCII': True,
- 'JSON_SORT_KEYS': True,
- 'JSONIFY_PRETTYPRINT_REGULAR': True,
- 'JSONIFY_MIMETYPE': 'application/json',
- 'TEMPLATES_AUTO_RELOAD': None,
- }
falsk 配置文件导入:
- # flask 配置文件介绍:
- # 方式一:
- # Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值
- # app.config['SECRET_KEY'] = '123456'
- # app.config['DEBUG'] = True
- # 方式二:(只有部分可以如此操作)
- # app.secret_key = '123456'
- # 方式三:(导入配置文件的方式)
- # app.config.from_pyfile('setting.py')
- # 方式四:(推荐方式:在配置文件中写一个类,将配置写在类里面,再导入)
- app.config.from_object('setting.Text')
方式四 setting文件
- # 共有的
- class Config(object):
- SECRET_KEY = ''
- DEBUG = False
- class Text(Config):
- DEBUG = True
- SECRET_KEY = 'abcd'
路由参数
- # 路由系统:
- # 基于装饰器来实现,但是究其本质是通过下面函数实现的
- # app.add_url_rule(rule='/路径',endpoint='别名',view_func='视图函数',methods='访问的类型/["GET","POST"]')
- # CBV 的flask 方式:
- # from flask import views
- # 配置视图
- # class Text(views.MethodView):
- # methods = ['GET','POST']
- # # 登录装饰器
- # # decorators = [login_required,]
- #
- # def get(self):
- # return 'Text_Class_get'
- #
- # def post(self):
- # return 'Text_Class,post'
- #
- # 配置路由
- # app.add_url_rule(rule='/text/',view_func=Text.as_view(name='text'))
- # app.add_url_rule 和 app.route
- # 参数:
- # rule: url 规则
- # view_func 视图函数名称
- # defaults=None 默认值,当url中没有参数
- # endpoint=None 反向生成url,不能重名,在使用装饰器时,没有导入@wraps(func)则需要区分
- # methods=None 允许的请求方式,如:['GET','POST']
- # strict_slashes=None 对URL最后的 / 符号是否严格要求
- # redirect_to=None 重定向地址
- # subdomain=None 子域名访问,需要配合域名使用
常用路由匹配方式
- # 常用路由方式:
- # @app.route('/user/<username>')
- # @app.route('/user/<int:post_id>')
- # @app.route('/user/<float:post_id>')
- # @app.route('/user/<path:PATH>')
- # @app.route('/user/',methods=['GET','POST'])
请求相关 & 响应
request
- # request
- # request.method
- # request.args
- # request.form
- # request.values
- # request.cookies
- # request.headers
- # request.path
- # request.full_path
- # request.script_root
- # request.url
- # request.base_url
- # request.url_root
- # request.host_url
- # request.host
- # request.files
- # obj = request=files['the_file_name']
- # obj.save('/var/www/uploads'+secure_filename(f.filename))
response
- # response
- # return "字符串"
- # render_templates('html模板',返回参数)
- # return redirect('/index.html')
- # 打包模板和参数
- # 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
模板 jinja2
- # 模板:(模板也支持导入,继承)
- # 跟 django 都是使用的jinja2 模板
- # 前段 安全渲染 {func | safe }
- # 后端 安全渲染 import Markup 函数
- # # 新增功能
- # {% macro 自定义函数名(参数,参数N) %}
- # <span>{{参数}}---{{参数n}}</span>
- # <span>{{参数}}---{{参数n}}</span>
- # <span>{{参数}}---{{参数n}}</span>
- # {% endmacro%}
- #
- # # 调用上面的函数
- # {{自定义函数(参数)}}
- # ------------
- # 模板内自定义函数(类似django simple_tag)
- # @app.template_global()
- # def sb(a1,a2):
- # return a1 + a2
- # 模板中使用方法:
- # {{sb(1,2)}}
- # ------------
- # 后端自定义前段函数
- # @app.template_filter()
- # def sb2(a1,a2,a3):
- # return a1 + a2 + a3
- # 模板中使用方法:
- # {{1|sb2(2,3)}}
- # url_for('参数') 参数指向的书 views 视图中的函数名,而不是路由名
请求扩展
- # 请求扩展 (django中的中间件)
- # 第一次访问执行:
- # @app.before_first_request
- # def first(*args,**kwargs)
- # pass
- # # 先进后出
- # @app.before_request
- # def preocess_request(*args,**kwargs):
- # # 这里可以做登录认证
- # print('request_1')
- #
- # @app.before_request
- # def preocess_request2(*args,**kwargs):
- # # 这里可以做登录认证
- # print('request_2')
- #
- # @app.after_request
- # def preocess_response(response):
- # print('response_1')
- # return response
- #
- # @app.after_request
- # def preocess_response2(response):
- # print('response_2')
- # return response
错误页面自定制
- # # 错误页面 自定制
- #
- # @app.errorhandler(404)
- # def error_404(arg):
- # return "页面不存在!"
闪现
- # # 闪现 : 临时数据操作 如:显示错误信息
- # from flask import flash,get_flashed_messages
- #
- # @app.route('/get')
- # def get():
- # data = get_flashed_messages()
- # # data = get_flashed_messages(category_filter=['l1']) 分类取数据
- # print(data)
- # return "get"
- #
- # @app.route('/set')
- # def set():
- # flash('aaaaaa')
- # # flash('aaaaaa',category='l1') #可以数据分类
- # return "set"
上下文管理
- # 上下文管理:
- # 1.知道flask 依赖的组件: WSGI、jinja2、Werkzeug,flask 框架是组装件的粘合剂
- # client --- wsgi -----flask --- jinja2 ----werkzeug
- # 2.flask 用threading.local 做了一个Local对象 存放请求信息
- # 引入步骤:
- # Flask()实例化 -> 将请求数据传入Flask实例 -> 将数据push 至 _request_ctx_stack,_request_ctx_stack实质是 LocalStack()
- # LocalStack() 初始化时 又实例化了 Local() ,local初始化 最终以类似列表的方式 保存object.__setattr__(self, '__storage__', {})
- # 请求到来:
- # --ctx = 封装requestContext(request,ssision)
- # --ctx放进Local中
- # 执行视图时
- # --导入request
- # --request ---> LocalProxy对象中 __getattr__获取对应的请求
- # ---调用 _lookup_req_object函数:去local 中酱requestcontext 将获取到,再去requestcontext中获取request或session
- # 请求结束
- # --ctx.auto_pop()
- # --ctx从local中移除
- # --> 上下文管理
- # --> threading.local
- # --> 请求上下文(requestContext)
- # --> request
- # --> session
- # --> 应用上下文: AppContext
- # --> app(current_app)
- # --> g
- # --> 实现细节
- # --> 利用threading.local的线程唯一ID标识符
- # --> requestcontext对象通过localstack添加到Local栈中
- # --> 导入request(session、current_app、g)是localproxy -> 偏函数 ->Localstack -> Local
- # --> requestcontext的auto_pop -> localstaack.pop ->local中移除
信号
- # # 示例一:(自定义信号)
- # from flask.signals import _signals
- #
- # xinhao = _signals.signal('before-render-template')#创建信号
- #
- # #定义函数
- # def wahaha(*args,**kwargs):
- # print("111",args,kwargs)
- #
- # # 将函数注册到信号中,添加到这个列表
- # xinhao.connect(wahaha)
- #
- # @app.route("/zzz")
- # def zzz():
- # # 信号是通过send 方法 出发的!!!!!!!!!
- # xinhao.send(sender='xxx',a1=123,a2=456) #触发这个信号,执行注册到这个信号列表中的所有函数,此处的参数个数需要与定义的函数中的参数一致
- # print("ok")
- # return "OK"
- # ---------------------------------------------------------------
- # # 示例二:(内置信号使用)
- # from flask.signals import _signals
- #
- # bf = _signals.signal('before-render-template')
- # bf2 = _signals.signal('template-rendered')
- #
- # def text(*args,**kwargs):
- # print("111")
- #
- # bf.connect(text)
- # bf2.connect(text)
信号与中间件的执行顺序
- # 信号 依赖于 blinker 模块 (信号只执行记录,并不能中断流程,而中间件可以中断)
- # pip install blinker
- # 内置信号 以及执行顺序:
- # --> a 中间件:before_first_request
- # --->1 appcontext_pushed = _signals.signal('appcontext-pushed') # 请求app上下文push时执行
- # --->2 request_started = _signals.signal('request-started') # 请求到来前执行
- # --> b 中间件:before_request
- # --->3 before_render_template = _signals.signal('before-render-template') # 模板渲染前执行
- # --->4.template_rendered = _signals.signal('template-rendered') # 模板渲染后执行
- # --> c 中间件:after_request
- # --> session.save_session()
- # --->5 request_finished = _signals.signal('request-finished') # 请求结束后执行
- # --->6.request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否)
- # --->7.appcontext_tearing_down = _signals.signal('appcontext-tearing-down') # 请求上下文执行完毕后自动执行(无论成功与否)
- # --->8.appcontext_popped = _signals.signal('appcontext-popped') # 请求上下文pop时执行
- # 发生在2 / 3 / 4 / 5或不执行
- # got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行
- # message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发
多APP 应用
- # 多APP 应用
- # web 访问多app应用时,上下文管理是如何实现的?
- # from werkzeug.wsgi import DispatcherMiddleware
- # from werkzeug.serving import run_simple
- #
- # app01 = Flask('app01')
- # app02 = Flask('app02')
- #
- # @app01.route('/index')
- # def app01_index():
- # return "app01"
- #
- # @app02.route('/index')
- # def app02_index():
- # return "app02"
- #
- # app = DispatcherMiddleware(app01,{
- # '/app02前缀':app02,
- # })
- #
- # if __name__=="__main__":
- # run_simple('localhost',8002,app)
session 相关
- #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
- # 使用session 前 必须配置SECRET_KEY!!!
- # session 操作:(session就相当于是一个字典!)
- # session['类型'] = 值
- # session.pop['类型']
- # del session['类型']
- #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
session 第三方组件(自定制session保存位置)
- # flask session 机制
- '''
- ->请求刚进来:获取随机字符串,存在,则去容器 中获取原来的个人数据,否则创建一个空的容器
- ->对象(随机字符串,{请求数据})
- ->视图:读取内存中对象
- ->响应:内存对象 将对象数据保存到数据库(没有指定数据库的话 保存在内存中),把随机字符串写到用户cookie中
- '''
- # 使用 方式一
- # flask-session 组件
- # from flask_session import Session
- # import pymongo
- #
- # app.config['SESSION_TYPE'] = 'mongodb' # session类型为redis
- #
- # app.config['SESSION_MONGODB'] = pymongo.MongoClient('localhost',27017)
- # app.config['SESSION_MONGODB_DB'] = 'text'
- # app.config['SESSION_MONGODB_COLLECT'] = 'col'
- #
- # app.config['SESSION_PERMANENT'] = True # 如果设置为True,则关闭浏览器session就失效。
- # app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密
- # app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀
- #
- # Session(app)
- # 使用 方式二
- # from flask_session import MongoDBSessionInterface
- # app.session_interface = MongoDBSessionInterface("参数!")
一些问答
- # &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
- # 问题1 多线程时如何体现的?
- # 问题2 flask的local 中保存数据时,使用列表创建出来的栈,为什么用栈?
- # --如果写web程序,web运行环境,栈中永远保存1条数据(可以不用栈)
- # --写脚本获取app信息,可能存在app上下文嵌套关系
- '''
- from flask import Flask,current_app,globals,_app_ctx_stack
- app1=Flask('app01')
- app1.debug = False
- app2=Flask('app02')
- app2.debug = False
- with app1.app_context():
- print(_app_ctx_stack._local.__storage__)
- print(current_app.config['DEBUG'])
- with app2.app_context():
- print(_app_ctx_stack._local.__storage__)
- print(current_app.config['DEBUG'])
- '''
- # &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
flask 实现装饰器方式:引入(wraps)
- from functools import wraps
- # flask 实现登录装饰器的功能
- def login_required(func):
- @wraps(func)
- # @wraps(view_func)的作用: 不改变使用装饰器原有函数的结构(如__name__, __doc__)
- # 不使用wraps可能出现的ERROR: view_func...endpoint...map...
- def wrapper(*args,**kwargs):
- if session.get('user'):
- return func(*args,**kwargs)
- else:
- return redirect('/')
- return wrapper
- # 装饰器实现的方式:
- @app.route('/index/',methods=['GET'])
- @login_required # flask 登录装饰器
- def index():
- return render_template('index.html',u_list=data)
- @app.route("/detail/<int:id>",methods=['GET'])
- def detail(id):
- return str(id)
python Flask web框架的更多相关文章
- Python Flask Web 框架入门
Python Flask 目录 本文主要借鉴 letiantian 的文章 http://www.letiantian.me/learn-flask/ 一.简介 二.安装 三.初始化Flask 四.获 ...
- 比我的脸还干的gan货——Python Flask Web 框架入门
Flask是一个轻量级的基于Python的web框架. 本文适合有一定HTML.Python.网络基础的同学阅读. 1. 简介 这份文档中的代码使用 Python 3 运行.是的,所以读者需要自己在电 ...
- Python之Web框架
Python之Web框架: 一. Web框架的本质: 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env pyth ...
- Python之Web框架们
Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. pip i ...
- python各种web框架对比
0 引言 python在web开发方面有着广泛的应用.鉴于各种各样的框架,对于开发者来说如何选择将成为一个问题.为此,我特此对比较常见的几种框架从性能.使用感受以及应用情况进行一个粗略的 ...
- 教程:在 Visual Studio 中开始使用 Flask Web 框架
教程:在 Visual Studio 中开始使用 Flask Web 框架 Flask 是一种轻量级 Web 应用程序 Python 框架,为 URL 路由和页面呈现提供基础知识. Flask 被称为 ...
- Python的WEB框架
Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. ? 1 2 ...
- Python之Web框架Django
Python之Web框架: Django 一. Django Django是一个卓越的新一代Web框架 Django的处理流程 1. 下载地址 Python 下载地址:https://www.pyt ...
- python 实现web框架simfish
python 实现web框架simfish 本文主要记录本人利用python实现web框架simfish的过程.源码github地址:simfish WSGI HTTP Server wsgi模块提供 ...
随机推荐
- 【转】Android开发:Service和Thread的关系
不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Th ...
- 好程序员分享居中一个float元素
好程序员分享居中一个float元素,我们布局的时候,用margin来设置float元素的外边距来达到效果.对于,在文档流中的元素,我们很容易让它水平居中,只要给元素设置一个固定的宽度,用margin: ...
- 微信小程序 初步认识一(微信运动步数)
1.注册微信小程序 2.安装小程序开发工具 3.实例(显示微信运动步数) 4.后端处理(c#) 一 注册微信小程序 注册地址:https://mp.weixin.qq.com/cgi-bin/regi ...
- MSIL学习------从HelloWorld开始
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3889z1y72b28 ...
- js 移除数组元素
//移除数组元素 Array.prototype.remove = function(val) { var index = this.indexOfArr(val); if (index > - ...
- Winform开发框架中工作流模块的动态处理
在工作流处理表中,首先我们区分流程模板和流程实例两个部分,这个其实就是类似模板和具体文档的概念,我们一份模板可以创建很多个类似的文档,文档样式结构类似的.同理,流程模板实例为流程实例后,就是具体的一个 ...
- 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控
前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...
- Entity Framework Core系列之DbContext(添加)
上一篇我们介绍了Entity Framework Core系列之DbContext,对DbContext有了概念上的了解,这篇将介绍DbContext添加数据 通过DbContext添加实体的主要方法 ...
- vue-百度地图-maker文字标签显示隐藏
html: <div id="allmap" class="map"></div> script: mounted() { th ...
- [Linux] Vim 撤销 回退 操作
在vi中按u可以撤销一次操作 u 撤销上一步的操作 Ctrl+r 恢复上一步被撤销的操作 注意: 如果你输入“u”两次,你的文本恢复原样,那应该是你的Vim被配置在Vi兼容 ...