目录:

--> 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 配置文件解析

  1. {
  2. 'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
  3. 'TESTING': False, 是否开启测试模式
  4. 'PROPAGATE_EXCEPTIONS': None,
  5. 'PRESERVE_CONTEXT_ON_EXCEPTION': None,
  6. 'SECRET_KEY': None,
  7. 'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
  8. 'USE_X_SENDFILE': False,
  9. 'LOGGER_NAME': None,
  10. 'LOGGER_HANDLER_POLICY': 'always',
  11. 'SERVER_NAME': None,
  12. 'APPLICATION_ROOT': None,
  13. 'SESSION_COOKIE_NAME': 'session',
  14. 'SESSION_COOKIE_DOMAIN': None,
  15. 'SESSION_COOKIE_PATH': None,
  16. 'SESSION_COOKIE_HTTPONLY': True,
  17. 'SESSION_COOKIE_SECURE': False,
  18. 'SESSION_REFRESH_EACH_REQUEST': True,
  19. 'MAX_CONTENT_LENGTH': None,
  20. 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
  21. 'TRAP_BAD_REQUEST_ERRORS': False,
  22. 'TRAP_HTTP_EXCEPTIONS': False,
  23. 'EXPLAIN_TEMPLATE_LOADING': False,
  24. 'PREFERRED_URL_SCHEME': 'http',
  25. 'JSON_AS_ASCII': True,
  26. 'JSON_SORT_KEYS': True,
  27. 'JSONIFY_PRETTYPRINT_REGULAR': True,
  28. 'JSONIFY_MIMETYPE': 'application/json',
  29. 'TEMPLATES_AUTO_RELOAD': None,
  30. }

falsk 配置文件导入:

  1. # flask 配置文件介绍:
  2. # 方式一:
  3. # Session, Cookies以及一些第三方扩展都会用到SECRET_KEY值
  4. # app.config['SECRET_KEY'] = '123456'
  5. # app.config['DEBUG'] = True
  6.  
  7. # 方式二:(只有部分可以如此操作)
  8. # app.secret_key = '123456'
  9.  
  10. # 方式三:(导入配置文件的方式)
  11. # app.config.from_pyfile('setting.py')
  12.  
  13. # 方式四:(推荐方式:在配置文件中写一个类,将配置写在类里面,再导入)
  14. app.config.from_object('setting.Text')

方式四 setting文件

  1. # 共有的
  2. class Config(object):
  3. SECRET_KEY = ''
  4. DEBUG = False
  5.  
  6. class Text(Config):
  7. DEBUG = True
  8. SECRET_KEY = 'abcd'

路由参数

  1. # 路由系统:
  2. # 基于装饰器来实现,但是究其本质是通过下面函数实现的
  3. # app.add_url_rule(rule='/路径',endpoint='别名',view_func='视图函数',methods='访问的类型/["GET","POST"]')
  4.  
  5. # CBV 的flask 方式:
  6. # from flask import views
  7. # 配置视图
  8. # class Text(views.MethodView):
  9. # methods = ['GET','POST']
  10. # # 登录装饰器
  11. # # decorators = [login_required,]
  12. #
  13. # def get(self):
  14. # return 'Text_Class_get'
  15. #
  16. # def post(self):
  17. # return 'Text_Class,post'
  18. #
  19. # 配置路由
  20. # app.add_url_rule(rule='/text/',view_func=Text.as_view(name='text'))
  21.  
  22. # app.add_url_rule 和 app.route
  23. # 参数:
  24. # rule: url 规则
  25. # view_func 视图函数名称
  26. # defaults=None 默认值,当url中没有参数
  27. # endpoint=None 反向生成url,不能重名,在使用装饰器时,没有导入@wraps(func)则需要区分
  28. # methods=None 允许的请求方式,如:['GET','POST']
  29. # strict_slashes=None 对URL最后的 / 符号是否严格要求
  30. # redirect_to=None 重定向地址
  31. # subdomain=None 子域名访问,需要配合域名使用

常用路由匹配方式

  1. # 常用路由方式:
  2. # @app.route('/user/<username>')
  3. # @app.route('/user/<int:post_id>')
  4. # @app.route('/user/<float:post_id>')
  5. # @app.route('/user/<path:PATH>')
  6. # @app.route('/user/',methods=['GET','POST'])

请求相关 & 响应

request

  1. # request
  2. # request.method
  3. # request.args
  4. # request.form
  5. # request.values
  6. # request.cookies
  7. # request.headers
  8. # request.path
  9. # request.full_path
  10. # request.script_root
  11. # request.url
  12. # request.base_url
  13. # request.url_root
  14. # request.host_url
  15. # request.host
  16.  
  17. # request.files
  18. # obj = request=files['the_file_name']
  19. # obj.save('/var/www/uploads'+secure_filename(f.filename))

response

  1. # response
  2. # return "字符串"
  3. # render_templates('html模板',返回参数)
  4. # return redirect('/index.html')
  5.  
  6. # 打包模板和参数
  7. # response = make_response(render_template("index.html"))
  8. # response 是flask.wrappers.Response类型
  9. # response.delete_cookie("key")
  10. # response.set_cookie("key",'value')
  11. # response.headers['X-something'] = 'A value'
  12. # return response

模板 jinja2

  1. # 模板:(模板也支持导入,继承)
  2. # 跟 django 都是使用的jinja2 模板
  3. # 前段 安全渲染 {func | safe }
  4. # 后端 安全渲染 import Markup 函数
  5.  
  6. # # 新增功能
  7. # {% macro 自定义函数名(参数,参数N) %}
  8. # <span>{{参数}}---{{参数n}}</span>
  9. # <span>{{参数}}---{{参数n}}</span>
  10. # <span>{{参数}}---{{参数n}}</span>
  11. # {% endmacro%}
  12. #
  13. # # 调用上面的函数
  14. # {{自定义函数(参数)}}
  15.  
  16. # ------------
  17.  
  18. # 模板内自定义函数(类似django simple_tag)
  19. # @app.template_global()
  20. # def sb(a1,a2):
  21. # return a1 + a2
  22.  
  23. # 模板中使用方法:
  24. # {{sb(1,2)}}
  25.  
  26. # ------------
  27. # 后端自定义前段函数
  28. # @app.template_filter()
  29. # def sb2(a1,a2,a3):
  30. # return a1 + a2 + a3
  31.  
  32. # 模板中使用方法:
  33. # {{1|sb2(2,3)}}
  34.  
  35. # url_for('参数') 参数指向的书 views 视图中的函数名,而不是路由名

请求扩展

  1. # 请求扩展 (django中的中间件)
  2.  
  3. # 第一次访问执行:
  4. # @app.before_first_request
  5. # def first(*args,**kwargs)
  6. # pass
  7.  
  8. # # 先进后出
  9. # @app.before_request
  10. # def preocess_request(*args,**kwargs):
  11. # # 这里可以做登录认证
  12. # print('request_1')
  13. #
  14. # @app.before_request
  15. # def preocess_request2(*args,**kwargs):
  16. # # 这里可以做登录认证
  17. # print('request_2')
  18. #
  19. # @app.after_request
  20. # def preocess_response(response):
  21. # print('response_1')
  22. # return response
  23. #
  24. # @app.after_request
  25. # def preocess_response2(response):
  26. # print('response_2')
  27. # return response

错误页面自定制

  1. # # 错误页面 自定制
  2. #
  3. # @app.errorhandler(404)
  4. # def error_404(arg):
  5. # return "页面不存在!"

闪现

  1. # # 闪现 : 临时数据操作 如:显示错误信息
  2. # from flask import flash,get_flashed_messages
  3. #
  4. # @app.route('/get')
  5. # def get():
  6. # data = get_flashed_messages()
  7. # # data = get_flashed_messages(category_filter=['l1']) 分类取数据
  8. # print(data)
  9. # return "get"
  10. #
  11. # @app.route('/set')
  12. # def set():
  13. # flash('aaaaaa')
  14. # # flash('aaaaaa',category='l1') #可以数据分类
  15. # return "set"

上下文管理

  1. # 上下文管理:
  2. # 1.知道flask 依赖的组件: WSGI、jinja2、Werkzeug,flask 框架是组装件的粘合剂
  3. # client --- wsgi -----flask --- jinja2 ----werkzeug
  4. # 2.flask 用threading.local 做了一个Local对象 存放请求信息
  5.  
  6. # 引入步骤:
  7. # Flask()实例化 -> 将请求数据传入Flask实例 -> 将数据push 至 _request_ctx_stack,_request_ctx_stack实质是 LocalStack()
  8. # LocalStack() 初始化时 又实例化了 Local() ,local初始化 最终以类似列表的方式 保存object.__setattr__(self, '__storage__', {})
  9.  
  10. # 请求到来:
  11. # --ctx = 封装requestContext(request,ssision)
  12. # --ctx放进Local中
  13. # 执行视图时
  14. # --导入request
  15. # --request ---> LocalProxy对象中 __getattr__获取对应的请求
  16. # ---调用 _lookup_req_object函数:去local 中酱requestcontext 将获取到,再去requestcontext中获取request或session
  17. # 请求结束
  18. # --ctx.auto_pop()
  19. # --ctx从local中移除
  20.  
  21. # --> 上下文管理
  22. # --> threading.local
  23. # --> 请求上下文(requestContext)
  24. # --> request
  25. # --> session
  26. # --> 应用上下文: AppContext
  27. # --> app(current_app)
  28. # --> g
  29. # --> 实现细节
  30. # --> 利用threading.local的线程唯一ID标识符
  31. # --> requestcontext对象通过localstack添加到Local栈中
  32. # --> 导入request(session、current_app、g)是localproxy -> 偏函数 ->Localstack -> Local
  33. # --> requestcontext的auto_pop -> localstaack.pop ->local中移除

信号

  1. # # 示例一:(自定义信号)
  2. # from flask.signals import _signals
  3. #
  4. # xinhao = _signals.signal('before-render-template')#创建信号
  5. #
  6. # #定义函数
  7. # def wahaha(*args,**kwargs):
  8. # print("111",args,kwargs)
  9. #
  10. # # 将函数注册到信号中,添加到这个列表
  11. # xinhao.connect(wahaha)
  12. #
  13. # @app.route("/zzz")
  14. # def zzz():
  15. # # 信号是通过send 方法 出发的!!!!!!!!!
  16. # xinhao.send(sender='xxx',a1=123,a2=456) #触发这个信号,执行注册到这个信号列表中的所有函数,此处的参数个数需要与定义的函数中的参数一致
  17. # print("ok")
  18. # return "OK"
  19.  
  20. # ---------------------------------------------------------------
  21.  
  22. # # 示例二:(内置信号使用)
  23. # from flask.signals import _signals
  24. #
  25. # bf = _signals.signal('before-render-template')
  26. # bf2 = _signals.signal('template-rendered')
  27. #
  28. # def text(*args,**kwargs):
  29. # print("111")
  30. #
  31. # bf.connect(text)
  32. # bf2.connect(text)

信号与中间件的执行顺序

  1. # 信号 依赖于 blinker 模块 (信号只执行记录,并不能中断流程,而中间件可以中断)
  2. # pip install blinker
  3.  
  4. # 内置信号 以及执行顺序:
  5. # --> a 中间件:before_first_request
  6. # --->1 appcontext_pushed = _signals.signal('appcontext-pushed') # 请求app上下文push时执行
  7. # --->2 request_started = _signals.signal('request-started') # 请求到来前执行
  8.  
  9. # --> b 中间件:before_request
  10. # --->3 before_render_template = _signals.signal('before-render-template') # 模板渲染前执行
  11. # --->4.template_rendered = _signals.signal('template-rendered') # 模板渲染后执行
  12.  
  13. # --> c 中间件:after_request
  14. # --> session.save_session()
  15. # --->5 request_finished = _signals.signal('request-finished') # 请求结束后执行
  16. # --->6.request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否)
  17.  
  18. # --->7.appcontext_tearing_down = _signals.signal('appcontext-tearing-down') # 请求上下文执行完毕后自动执行(无论成功与否)
  19. # --->8.appcontext_popped = _signals.signal('appcontext-popped') # 请求上下文pop时执行
  20.  
  21. # 发生在2 / 3 / 4 / 5或不执行
  22. # got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行
  23.  
  24. # message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发

多APP 应用

  1. # 多APP 应用
  2. # web 访问多app应用时,上下文管理是如何实现的?
  3.  
  4. # from werkzeug.wsgi import DispatcherMiddleware
  5. # from werkzeug.serving import run_simple
  6. #
  7. # app01 = Flask('app01')
  8. # app02 = Flask('app02')
  9. #
  10. # @app01.route('/index')
  11. # def app01_index():
  12. # return "app01"
  13. #
  14. # @app02.route('/index')
  15. # def app02_index():
  16. # return "app02"
  17. #
  18. # app = DispatcherMiddleware(app01,{
  19. # '/app02前缀':app02,
  20. # })
  21. #
  22. # if __name__=="__main__":
  23. # run_simple('localhost',8002,app)

session 相关

  1. #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  2. # 使用session 前 必须配置SECRET_KEY!!!
  3. # session 操作:(session就相当于是一个字典!)
  4. # session['类型'] = 值
  5. # session.pop['类型']
  6. # del session['类型']
  7. #&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

session 第三方组件(自定制session保存位置)

  1. # flask session 机制
  2. '''
  3. ->请求刚进来:获取随机字符串,存在,则去容器 中获取原来的个人数据,否则创建一个空的容器
  4. ->对象(随机字符串,{请求数据})
  5. ->视图:读取内存中对象
  6. ->响应:内存对象 将对象数据保存到数据库(没有指定数据库的话 保存在内存中),把随机字符串写到用户cookie中
  7. '''
  8. # 使用 方式一
  9. # flask-session 组件
  10. # from flask_session import Session
  11. # import pymongo
  12. #
  13. # app.config['SESSION_TYPE'] = 'mongodb' # session类型为redis
  14. #
  15. # app.config['SESSION_MONGODB'] = pymongo.MongoClient('localhost',27017)
  16. # app.config['SESSION_MONGODB_DB'] = 'text'
  17. # app.config['SESSION_MONGODB_COLLECT'] = 'col'
  18. #
  19. # app.config['SESSION_PERMANENT'] = True # 如果设置为True,则关闭浏览器session就失效。
  20. # app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密
  21. # app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀
  22. #
  23. # Session(app)
  24.  
  25. # 使用 方式二
  26.  
  27. # from flask_session import MongoDBSessionInterface
  28. # app.session_interface = MongoDBSessionInterface("参数!")

一些问答

  1. # &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
  2. # 问题1 多线程时如何体现的?
  3. # 问题2 flask的local 中保存数据时,使用列表创建出来的栈,为什么用栈?
  4. # --如果写web程序,web运行环境,栈中永远保存1条数据(可以不用栈)
  5. # --写脚本获取app信息,可能存在app上下文嵌套关系
  6.  
  7. '''
  8. from flask import Flask,current_app,globals,_app_ctx_stack
  9.  
  10. app1=Flask('app01')
  11. app1.debug = False
  12.  
  13. app2=Flask('app02')
  14. app2.debug = False
  15.  
  16. with app1.app_context():
  17. print(_app_ctx_stack._local.__storage__)
  18. print(current_app.config['DEBUG'])
  19.  
  20. with app2.app_context():
  21. print(_app_ctx_stack._local.__storage__)
  22. print(current_app.config['DEBUG'])
  23.  
  24. '''
  25. # &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

flask 实现装饰器方式:引入(wraps)

  1. from functools import wraps
  2. # flask 实现登录装饰器的功能
  3. def login_required(func):
  4. @wraps(func)
  5. # @wraps(view_func)的作用: 不改变使用装饰器原有函数的结构(如__name__, __doc__)
  6. # 不使用wraps可能出现的ERROR: view_func...endpoint...map...
  7. def wrapper(*args,**kwargs):
  8. if session.get('user'):
  9. return func(*args,**kwargs)
  10. else:
  11. return redirect('/')
  12. return wrapper
  13.  
  14. # 装饰器实现的方式:
  15. @app.route('/index/',methods=['GET'])
  16. @login_required # flask 登录装饰器
  17. def index():
  18. return render_template('index.html',u_list=data)
  19.  
  20. @app.route("/detail/<int:id>",methods=['GET'])
  21. def detail(id):
  22. return str(id)

python Flask web框架的更多相关文章

  1. Python Flask Web 框架入门

    Python Flask 目录 本文主要借鉴 letiantian 的文章 http://www.letiantian.me/learn-flask/ 一.简介 二.安装 三.初始化Flask 四.获 ...

  2. 比我的脸还干的gan货——Python Flask Web 框架入门

    Flask是一个轻量级的基于Python的web框架. 本文适合有一定HTML.Python.网络基础的同学阅读. 1. 简介 这份文档中的代码使用 Python 3 运行.是的,所以读者需要自己在电 ...

  3. Python之Web框架

    Python之Web框架: 一.  Web框架的本质: 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env pyth ...

  4. Python之Web框架们

    Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. pip i ...

  5. python各种web框架对比

    0 引言        python在web开发方面有着广泛的应用.鉴于各种各样的框架,对于开发者来说如何选择将成为一个问题.为此,我特此对比较常见的几种框架从性能.使用感受以及应用情况进行一个粗略的 ...

  6. 教程:在 Visual Studio 中开始使用 Flask Web 框架

    教程:在 Visual Studio 中开始使用 Flask Web 框架 Flask 是一种轻量级 Web 应用程序 Python 框架,为 URL 路由和页面呈现提供基础知识. Flask 被称为 ...

  7. Python的WEB框架

    Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Python的标准库外,其不依赖任何其他模块. ? 1 2 ...

  8. Python之Web框架Django

    Python之Web框架: Django 一. Django Django是一个卓越的新一代Web框架 Django的处理流程 1. 下载地址  Python 下载地址:https://www.pyt ...

  9. python 实现web框架simfish

    python 实现web框架simfish 本文主要记录本人利用python实现web框架simfish的过程.源码github地址:simfish WSGI HTTP Server wsgi模块提供 ...

随机推荐

  1. 【转】Android开发:Service和Thread的关系

    不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Th ...

  2. 好程序员分享居中一个float元素

    好程序员分享居中一个float元素,我们布局的时候,用margin来设置float元素的外边距来达到效果.对于,在文档流中的元素,我们很容易让它水平居中,只要给元素设置一个固定的宽度,用margin: ...

  3. 微信小程序 初步认识一(微信运动步数)

    1.注册微信小程序 2.安装小程序开发工具 3.实例(显示微信运动步数) 4.后端处理(c#) 一 注册微信小程序 注册地址:https://mp.weixin.qq.com/cgi-bin/regi ...

  4. MSIL学习------从HelloWorld开始

    我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3889z1y72b28 ...

  5. js 移除数组元素

    //移除数组元素 Array.prototype.remove = function(val) { var index = this.indexOfArr(val); if (index > - ...

  6. Winform开发框架中工作流模块的动态处理

    在工作流处理表中,首先我们区分流程模板和流程实例两个部分,这个其实就是类似模板和具体文档的概念,我们一份模板可以创建很多个类似的文档,文档样式结构类似的.同理,流程模板实例为流程实例后,就是具体的一个 ...

  7. 基于 HTML5 的 WebGL 楼宇自控 3D 可视化监控

    前言 智慧楼宇和人们的生活息息相关,楼宇智能化程度的提高,会极大程度的改善人们的生活品质,在当前工业互联网大背景下受到很大关注.目前智慧楼宇可视化监控的主要优点包括: 智慧化 -- 智慧楼宇是一个生态 ...

  8. Entity Framework Core系列之DbContext(添加)

    上一篇我们介绍了Entity Framework Core系列之DbContext,对DbContext有了概念上的了解,这篇将介绍DbContext添加数据 通过DbContext添加实体的主要方法 ...

  9. vue-百度地图-maker文字标签显示隐藏

    html: <div id="allmap" class="map"></div>   script:   mounted() { th ...

  10. [Linux] Vim 撤销 回退 操作

    在vi中按u可以撤销一次操作 u   撤销上一步的操作      Ctrl+r 恢复上一步被撤销的操作 注意:        如果你输入“u”两次,你的文本恢复原样,那应该是你的Vim被配置在Vi兼容 ...