app = Flask(__name__)

1.创建static文件夹

static_path = '/static' # 在flask类中# 所有的instance都共享flask class中的static_path
if self.static_path is not None: # 若果静态文件存在,则通过ShareDatMiddleware设置静态文件夹self.url_map.add(Rule(self.static_path + '/<filename>',build_only=True, endpoint='static')) # 添加静态文件urltarget = os.path.join(self.root_path, 'static') # 如果是主程序则拼贴`static`的路径self.wsgi_app = SharedDataMiddleware(self.wsgi_app, { # 添加中间件self.static_path: target # ??})

2.url_for

def url_for(endpoint, **values):return _request_ctx_stack.top.url_adapter.build(endpoint, values)

3.flash

# 模块中的方法
def flash(message):session['_flashes'] = (session.get('_flashes', [])) + [message]# 模块中的方法
def get_flashed_messages():flashes = _request_ctx_stack.top.flashesif flashes is None: # _request_ctx_stack_request_ctx_stack.top.flashes = flashes = \session.pop('_flashes', [])return flashes

4.获得app.py路径,无论在哪运行都能找到app.py工程

self.package_name = package_name
self.root_path = _get_package_path(self.package_name)def _get_package_path(name):return os.path.abspath(os.path.dirname(sys.modules[name].__file__))

5.视图函数 与 路由规则

self.view_functions = {}
self.url_map = Map()def route(self, rule, **options): # 路由处理def decorator(f):self.add_url_rule(rule, f.__name__, **options) # 给url起名字self.view_functions[f.__name__] = f # 给view_function起相同的名字return freturn decorator
# 在我们写入
# @app.route("./index")
# def index():
# 时调用此装饰函数,将它加入到视图函数与路由规则中def add_url_rule(self, rule, endpoint, **options): # 添加URL_RULEoptions['endpoint'] = endpointoptions.setdefault('methods', ('GET',))self.url_map.add(Rule(rule, **options))

6.预处理函数

self.before_request_funcs = []def before_request(self, f):"""Registers a function to run before each request."""self.before_request_funcs.append(f)return f# 当我们在写入
# @before_request
# def somefunc():
# 时调用此装饰函数,将它加入到预处理函数列表中

7.后处理函数

self.after_request_funcs = []
def after_request(self, f):self.after_request_funcs.append(f)return f
# 同6、7,主要用于

8.错误处理函数+

self.error_handlers = {}def errorhandler(self, code):def decorator(f):self.error_handlers[code] = freturn freturn decorator

9.jinja渲染

#1在视图函数中调用,返回jinja模板
def render_template(template_name, **context): # modulecurrent_app.update_template_context(context) # current只能在线程中使用return current_app.jinja_env.get_template(template_name).render(context)#1.1更新上下文,将方法传入页面,所以我们可以在jinja模板中直接使用request等
def update_template_context(self, context): #更新template 上下文reqctx = _request_ctx_stack.topfor func in self.template_context_processors:context.update(func())self.template_context_processors = [_default_template_ctx_processor]
def _default_template_ctx_processor():reqctx = _request_ctx_stack.topreturn dict(request=reqctx.request,session=reqctx.session,g=reqctx.g)#1.2返回jinja
self.jinja_env = Environment(loader=self.create_jinja_loader(),**self.jinja_options) # 配置jinjia2
self.jinja_env.globals.update(url_for=url_for,get_flashed_messages=get_flashed_messagesjinja_options = dict(  autoescape=True,extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
)
def create_jinja_loader(self): # 添加jinja2的载入,默认是`templates` # 实例方法if pkg_resources is None:return FileSystemLoader(os.path.join(self.root_path, 'templates'))return PackageLoader(self.package_name)#2.此外添加jinjia文本渲染的方法,有默认值
@app.app_context_processor
def admin_email()def context_processor(self, f): # 添加context_processorsself.template_context_processors.append(f)return f

7.请求处理:

#1 当我们调用app.run()时本质调用了sun_simple()
def run(self, host='localhost', port=5000, **options):from werkzeug import run_simpleif 'debug' in options:self.debug = options.pop('debug')options.setdefault('use_reloader', self.debug)options.setdefault('use_debugger', self.debug)return run_simple(host, port, self, **options)#2 run_simple中第3个三参数是self,既app本身,既app中的__call__方法
# __call__方法返回了wsgi_app()
def __call__(self, environ, start_response):return self.wsgi_app(environ, start_response)#3 wsgi_app
def wsgi_app(self, environ, start_response): # 真实的WSGI application,在__call__中调用with self.request_context(environ):rv = self.preprocess_request() # 首先调用预处理请求函数if rv is None: # 如果预处理后,返回为None,??rv = self.dispatch_request() # 这时可能返回字符串,也可能是responseclassresponse = self.make_response(rv) # 进一步处理,比如如果是response = self.process_response(response) # 保存sessionreturn response(environ, start_response)
#3.1 首先打开了上下文request_context(environ)
def request_context(self, environ):return _RequestContext(self, environ)# 返回的是_RequestContext对象,这对象存放了
# app
# url_adapter 绑定了environ,所以可以调用match来根据url获得endpoints,继而获得function
# request 获得当前environ对应的request instance
# session 获得当前session,其实就是cookie
# g _RequestGlobals()
class _RequestContext(object): # 使用with语句,拿到栈顶的request进行处理def __init__(self, app, environ):self.app = app # 当前的appself.url_adapter = app.url_map.bind_to_environ(environ) # 主要用来处理URL,因为绑定了environ以后就不需要再往match里传递参数了self.request = app.request_class(environ) # 当前的请求信息self.session = app.open_session(self.request) # 当前的会话信息 secret_key = None 类中设定,所有app共享self.g = _RequestGlobals() # ?这个地方还没写self.flashes = None # ?这个地方也没写
# 载入上下文时,将当前的app 压入_request_ctx_stack 栈中def __enter__(self): # 使用with语句_request_ctx_stack.push(self) # 将当前请求推入栈
# 离开上下文时,将当前的app 弹出栈def __exit__(self, exc_type, exc_value, tb):# do not pop the request stack if we are in debug mode and an# exception happened.  This will allow the debugger to still# access the request object in the interactive shell.if tb is None or not self.app.debug:_request_ctx_stack.pop() # 将往前请求推出栈#3.2 调用preprocess_request()方法进行请求预处理,返回rule和values
def preprocess_request(self):for func in self.before_request_funcs:rv = func()if rv is not None: # 这里不需要判断,因为在调用preprocess_request,后又做了判断return rv#3.3 如果preprocess_request()返回为None,则调用dispatch_request,用我们定义的视图函数来处理。比如验证是否登录。
def dispatch_request(self):try:endpoint, values = self.match_request()return self.view_functions[endpoint](**values)except HTTPException, e:handler = self.error_handlers.get(e.code)if handler is None:return ereturn handler(e)except Exception, e:handler = self.error_handlers.get(500)if self.debug or handler is None:raisereturn handler(e)#3.4 调用make_response,该方法强制将rv转换成response对象
def make_response(self, rv):if isinstance(rv, self.response_class):return rvif isinstance(rv, basestring):return self.response_class(rv)if isinstance(rv, tuple):return self.response_class(*rv)return self.response_class.force_type(rv, request.environ)#3.5 调用process_response,在response对象返回给WSGI server之前,进行操作,比如设置session等,返回值还会受到.after_request_funcs操作。
def process_response(self, response):session = _request_ctx_stack.top.sessionif session is not None:self.save_session(session, response)for handler in self.after_request_funcs:response = handler(response)return response#存储session
# 在_RequestContext调用oepn_sesion方法获得session,实际调用的是SecureCookie,既存储在cookie中self.session = app.open_session(self.request)
def open_session(self, request): # 会话,通过cookie来实现key = self.secret_keyif key is not None:return SecureCookie.load_cookie(request, self.session_cookie_name,secret_key=key)
def save_session(self, session, response):if session is not None: # 如果不为空,则更新sessionsession.save_cookie(response, self.session_cookie_name)session_cookie_name = 'session' # Flask类中定义 所有app共享

参考:
理解current
需要注意的是current_app是“线程”本地变量,所以current_app需要在视图函数或命令行函数中使用,否则也会报错。
https://blog.csdn.net/JENREY/article/details/86606653

flask v0.1 执行流程 Flask(__name__)相关推荐

  1. flask v0.1 内部运行程序

    Werkzeug is an HTTP and WSGI utility library for Python.提供: 1.WSGI server 类似于tomcat,是一个server 容器 2.对 ...

  2. python flask 路由_python框架之Flask(2)-路由和视图Session

    路由和视图 这一波主要是通过看源码加深对 Flask 中路由和视图的了解,可以先回顾一下装饰器的知识:[装饰器函数与进阶] 路由设置的两种方式 #示例代码 from flask importFlask ...

  3. flask 第八篇 实例化flask时的参数配置

    Flask 是一个非常灵活且短小精干的web框架 , 那么灵活性从什么地方体现呢? 有一个神奇的东西叫 Flask配置 , 这个东西怎么用呢? 它能给我们带来怎么样的方便呢? 首先展示一下: from ...

  4. Flask后端实践 连载十三 Flask输出Excel报表

    Flask后端实践 连载十三 Flask输出Excel报表 tips: 简单实现Flask输出Excel报表 本文基于python3编写 代码仓库 项目场景 由于项目是工程上的使用,不仅需要对采集的数 ...

  5. djangorestframework源码分析2:serializer序列化数据的执行流程

    djangorestframework源码分析 本文环境python3.5.2,djangorestframework (3.5.1)系列 djangorestframework源码分析-serial ...

  6. djangorestframework源码分析1:generics中的view执行流程

    djangorestframework源码分析 本文环境python3.5.2,djangorestframework (3.5.1)系列 djangorestframework源码分析-generi ...

  7. python 装饰器实现缓存_Python, 这一个缓存装饰器, 其执行流程是怎样的?

    2017/2/6 描述 比如, 考虑这样一段代码, 它的执行流程是怎样的呢 ? class Foo(object): @cached_property def foo(self): # calcula ...

  8. flask tutorial = make a blog :) flask 搭建博客系统从零开始!

    please follow the tutorial from the official site :) http://flask.pocoo.org/docs/ You could download ...

  9. python flask高级编程之restful_python Flask实现restful api service

    一直在用node.js做后端,要逐步涉猎大数据范围,注定绕不过python,因此决定把一些成熟的东西用python来重写,一是开拓思路.通过比较来深入学习python:二是有目标,有动力,希望能持之以 ...

最新文章

  1. hive常见问题及解决方法
  2. 利用 FastCoding 将对象进行本地持久化
  3. 微信朋友圈装x代码_NBA总决赛朋友圈装X图鉴:直男之间有真正的友谊吗?
  4. 年轻人买菜只愿意走670米,每日优鲜、叮咚买菜等生鲜电商们依然“难送达”
  5. 加载如下html 写出输出顺序,浏览器加载和渲染html的顺序-结论篇
  6. c语言键盘控制数码管显示,3*4矩阵键盘控制4位数码管显示的C程序
  7. Java 进阶—— super 和 this 的用法
  8. 基于YOLOv3 与CRNN的中文自然场景文字检测与识别
  9. 物理学与计算机相关参考文献,物理学专业论文参考文献
  10. SpringMVC后台数据校验
  11. win7下U盘安装Ubuntu16.04双系统
  12. JS 学习笔记--8---Function类型
  13. 报价单,要这样做才专业
  14. WA47电子管麦克风
  15. 宝塔+云锁nginx自编译web防护 防御CC效果极佳
  16. Android 改变View的中心点
  17. STM32F103RCT6+BTN7971B+JGB37-520+PWM驱动电机
  18. linux 常见服务
  19. xshell 免费版申请
  20. Wormhole漏洞分析

热门文章

  1. 中小学生Python课应该学什么
  2. Python花式编程案例锦集(4)
  3. 详解Python字符串编码格式
  4. Python分离GIF动画成为多帧图像
  5. Windows下如何安装MySQL服务
  6. 手机号星号_word把个人信息中的手机号其中四位设成星号的操作步骤图解
  7. php外贸后台,…外贸购物商城网站开发… PHP开发 提供源代码 外贸网站案例 直接购买案例 雇佣兵网...
  8. linux chmod修改权限失败,Linux chmod修改文件夹权限
  9. c位边上还有什么位_会议桌C位,是它!
  10. python内存管理错误的是_Python内存管理机制