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模块提供 ...
随机推荐
- luogu P4842 城市旅行
嘟嘟嘟 好题,好题 刚开始突发奇想写了一个\(O(n ^ 2)\)暴力,结果竟然过了?!后来才知道是上传题的人把单个数据点开成了10s-- 不过不得不说我这暴力写的挺好看的.删边模仿链表删边,加边的时 ...
- http协议进阶(五)连接管理
几乎所有的HTTP通信都是由TCP/IP承载的,TCP/IP是全球计算机网络设备都在使用的一种分组交换网络分层协议集. 它的特点是只要连接建立,客户端与服务器之间的报文交换就永远不会丢失.受损或失序. ...
- Maven基础入门与核心知识
Apache Maven是一个软件项目管理和综合工具.基于项目对象模型(POM)的概念,Maven可以从一个中心资料片管理项目构建,报告和文件. Maven是一个项目管理和综合工具.Maven提供了开 ...
- sklearn.neural_network.MLPClassifier参数说明
目录 sklearn.neural_network.MLPClassifier sklearn.neural_network.MLPClassifier MLPClassifier(hidden_la ...
- 查看CLOUD系统级IIS日志
1.进入IIS,点击查看日志文件 2.分不同文件夹存放
- Shell命令-文件及内容处理之cat、tac
文件及内容处理 - cat.tac 1. cat:显示文件内容 cat命令的功能说明 cat命令用于连接多个文件并且打印到屏幕输出或重定向到指定文件中 cat命令的语法格式 cat [OPTION]. ...
- Linux--主从复制
一 . mysql+centos7 mariadb mariadb其实是跟mysql是一样的,只不过是在centos7上叫做mariadb, 主要是因为mysql被甲骨文公司收购后,可能会有闭源的风险 ...
- golang 数组、切片、map
一.数组(类似python的list) 数组的长度一旦定义了就不能动态增长.并且存储的数据类型必须相同. 创建方法: var 数组名 [长度]数据类型 例如: package main import ...
- Comparable vs Comparator
Comparable interface can be used to provide single way of sorting whereas Comparator interface is us ...
- [模板] 匈牙利算法&&二分图最小字典序匹配
匈牙利算法 简介 匈牙利算法是一种求二分图最大匹配的算法. 时间复杂度: 邻接表/前向星: \(O(n * m)\), 邻接矩阵: \(O(n^3)\). 空间复杂度: 邻接表/前向星: \(O(n ...