Flask框架
STEP-1
一.flask简介
1 | """ |
二.flask安装
1 | pip3 install flask |
三.werkzeug
3.1 简介
1 | """ |
3.2 示例
1 | from werkzeug.wrappers import Request, Response |
1 | """ |
四.flask的快速使用
4.1 首先导入Flask这个类
1 | from flask import Flask |
4.2 实例化产生一个Flask的对象
1 | app = Flask(__name__) |
4.3 设置成调试模式,自动刷新重启
1 | app.debug = True |
4.4 写视图函数并配置路由
1 |
|
4.5 启动flask项目
1 | if __name__ == "__main__": |
4.6 示例
1 | from flask import Flask |
五. 基于Flask写一个项目具备:登录,显示用户信息
5.1 目录结构
1 | """ |
5.2 flask_damon.py
1 | from flask import Flask, render_template, redirect, session, request |
5.3 login.html
1 |
|
1 | """ |
5.4 user_list.html
1 |
|
1 | """ |
5.5 user_detail.html
1 |
|
1 | """ |
六. 基于flask的登录认证装饰器
1 | from flask import Flask, render_template, redirect, session, request, url_for |
1 | """ |
STEP-2
一. Flask的配置文件
1.1 默认的配置文件是一个flask.config.Config对象(继承字典)
1 | """ |
源码 | 作用 |
---|---|
‘DEBUG’: None | 启用/禁止调试模式 |
‘TESTING’: False | 启用/禁止测试模式 |
‘PROPAGATE_EXCEPTIONS’: None | 显式地启用或者禁止异常的传播。如果没有设置或显式设置为None,当TESTING或DEBUG为真时,隐式为真 |
‘PRESERVE_CONTEXT_ON_EXCEPTION’: None | 默认情况下,如果应用工作在调试模式, 请求上下文不会在异常时出栈来允许调试器内省。 这可以通过这个键来禁用。 你同样可以用这个设定来强制启用它, 即使没有调试执行,这对调试生产应用很有用 (但风险也很大) |
‘SECRET_KEY’: None | 密钥,使用session时需要使用 |
‘PERMANENT_SESSION_LIFETIME’: timedelta(days=31) | 一个持久化的会话的生存时间,作为一个datetime.timedelta 对象。从 Flask0.8 开始 也可以用一个整数来表示秒。 |
‘USE_X_SENDFILE’: False | 启用/禁止x-sendfile |
‘SERVER_NAME’: None | 服务器的名称以及端口,需要它为了支持子域名 (如: 'myapp.dev:5000' )。注意 localhost 是 不支持子域名的因此设置成 “localhost” 是无意义的。 设置 SERVER_NAME 默认会允许在没有请求上下文 而仅有应用上下文时生成 URL。 |
‘APPLICATION_ROOT’: ‘/‘ | 如果应用不占用完整的域名或子域名, 这个选项可以被设置为应用所在的路径。 这个路径也会用于会话 cookie 的路径值。 如果直接使用域名,则留作 None 。 |
‘SESSION_COOKIE_NAME’: ‘session’ | 会话cookie的名称 |
‘SESSION_COOKIE_DOMAIN’: None | 会话cookie的域,如果没有设置的话,cookie将会对SERVER_NAME所有的子域有效。 |
‘SESSION_COOKIE_PATH’: None | 会话cookie的路径。如果没有设置或者没有为’/‘设置,cookie将会对所有的APPLICATION_ROOT有效. |
‘SESSION_COOKIE_HTTPONLY’: True | 控制cookie是否应被设置httponly的标志,默认为True。 |
‘SESSION_COOKIE_SECURE’: False | 控制cookie是否应被设置安全标志,默认为False。 |
‘MAX_CONTENT_LENGTH’: None | 如果设置为字节数,Flask会拒绝内容长度大于此值的请求进入,并返回一个413的状态码。 |
‘SEND_FILE_MAX_AGE_DEFAULT’: timedelta(hours=12) | 默认缓存控制的最大期限,以秒计, 在 send_static_file() (默认的静态文件处理器)和 send_file() 中使用。 对于单个文件,覆盖这个值,使用 get_send_file_max_age() 勾住Flask 或者 Blueprint 。 默认为 43200(12小时)。 |
‘TRAP_BAD_REQUEST_ERRORS’: None | Werkzeug 处理请求中的特定数据的内部数据结构会 抛出同样也是“错误的请求”异常的特殊的 key errors 。 同样地,为了保持一致,许多操作可以 显式地抛出 BadRequest 异常。因为在调试中, 你希望准确地找出异常的原因, 这个设置用于在这些情形下调试。 如果这个值被设置为 True , 你只会得到常规的回溯。 |
‘TRAP_HTTP_EXCEPTIONS’: False | 如果这个值被设置为 True , Flask 不会执行 HTTP 异常的错误处理, 而是像对待其它异常一样,通过异常栈让它冒泡。 这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。 |
‘PREFERRED_URL_SCHEME’: ‘http’ | url模式用于url生成。如果没有设置url模式,默认将为http。 |
‘JSON_AS_ASCII’: True | 默认情况下 Flask 序列化对象成 ascii 编码的 JSON。 如果不对该配置项就行设置的话,Flask 将不会编码成 ASCII 保持字符串原样,并且返回 unicode 字符串。jsonfiy 会自动按照 utf-8 进行编码并且传输。 |
‘JSON_SORT_KEYS’: True | 默认情况下 Flask 将会依键值顺序的方式序列化 JSON。 这样做是为了确保字典哈希种子的独立性,返回值将会一致不会造成 额外的 HTTP 缓存。通过改变这个变量可以重载默认行为。 这是不推荐也许会带来缓存消耗的性能问题。 |
‘JSONIFY_PRETTYPRINT_REGULAR’: False | 如果设置成 True (默认下),jsonify 响应将会完美地打印。 |
1.2 配置文件的方式一:通过config对象字典特性
1 | app.config["DEBUG"] = True |
1.3 配置文件方式二:通过py文件配置
1 | app.config.from_pyfile("python文件名称") |
1.4 配置文件方式三:通过环境变量配置
1 | app.config.from_ecvvar("环境变量名称") |
1.5 配置文件方式四:通过json文件
1 | app.config.from_json("json文件名称") |
1.6 配置文件方式五:通过字典映射
1 | app.config.from_mapping({"DEBUG":True}) |
1.7 配置文件方式六:通过对象的方式
1 | app.config.from_object("python类或类的路径") |
1.7.1 实例
1 | # settings.py文件中 |
1 | """ |
1.8 配置文件的路径问题
1 |
|
二. Flask的路由系统
2.1 路由的典型写法
1 |
2.2 默认的内置转换器
1 |
|
2.3 自定义正则转换器
2.3.1 写一个类继承BaseConverter
1 | # 自定义转换器,支持正则 |
2.3.2 注册转换器
1 | app.url_map.converters["regex"] = RegexConverter |
2.3.3 使用转换器
1 |
|
2.3.4 注意
1 | 2.3.2和2.3.3中的regex名字必须一致 |
2.4 路由的本质
2.4.0 执行流程
1 | """ |
2.4.1 例子代码
1 |
|
2.4.2 源码分析:route
route方法的分析
1 |
|
2.4.3 源码分析:add_url_rule
add_url_rule方法的分析
1 | def add_url_rule(self, rule, endpoint=None, view_func=None, |
2.4.4 源码分析:_endpoint_from_view_func
_endpoint_from_view_func
1 | def _endpoint_from_view_func(view_func): |
2.4.5 源码分析:url_rule_class
1 | """ |
1 | class Rule(RuleFactory): |
2.4.6 源码分析:self.url_map.add(rule)
1 | """ |
1 | def add(self, rulefactory): |
1 | def get_rules(self, map): |
1 | def bind(self, map, rebind=False): |
2.4.7 装饰器执行流程
1 | """ |
2.4.8 例子代码改写
1 | def user_list(): |
2.5 CBV源码解析
2.5.1 例子代码
1 | from flask import Flask, views, session, redirect |
2.5.1 as_view
1 | """ |
1 | def as_view(cls, name, *class_args, **class_kwargs): |
2.5.2 dispatch_request
1 | """ |
1 | def dispatch_request(self, *args, **kwargs): |
2.5.3 MethodViewType元类的作用
1 | """ |
1 | class MethodViewType(type): |
2.6 add_url_rule参数
2.6.1 rule
1 | URL规则,如"/" |
2.6.2 view_func
1 | 视图函数名称 |
2.6.3 defaults
1 | defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}为函数提供参数 |
2.6.4 endpoint
1 | endpoint = None, 名称,用于反向生成URL,即: url_for('名称') |
2.6.5 methods
1 | methods = None, 允许的请求方式,如:["GET", "POST"] |
2.6.6 strict_slashes
1 | 对URL最后的 / 符号是否严格要求 |
2.6.7 redirect_to
1 | 重定向到指定地址 |
2.6.8 subdomain
1 | 子域名访问 |
三.Flask的模板语言(依赖于jinjia2)
3.1 和django模板的不同
1 | 比django中多可以加括号,执行函数,传参数 |
3.2 实例
3.2.1 视图
1 | from flask import Flask, render_template, Markup, jsonify, make_response |
3.2.2 模板
1 |
|
3.3 flask处理了xss攻击,如果想显示原生html
1 | safe:模板中 |
3.4 注意
1 | 1.Markup等价django的mark_safe |
3.5 标签:template_global
3.5.1 使用
1 | 通过template_global装饰后,可以直接在模板html文件中通过{{标签名(参数,参数)}}使用 |
1 |
|
3.5.2 实例
html
1 |
|
view
1 | from flask import Flask, render_template |
3.6 过滤器:template_filter
3.6.1 使用
1 | 通过template_filter装饰后,可以直接在模板html文件中通过{{ 参数1 | 标签名(参数2,参数3)}}使用 |
3.6.2 实例
html
1 |
|
view
1 | from flask import Flask, render_template |
四. Flask的请求与响应
4.1 request
1 | # 请求相关信息 |
1 | """ |
4.2 response
1 | # return "字符串" |
4.3 往响应头里面加东西
1 | # from flask import make_response |
4.4 参考实例
1 | from flask import Flask, jsonify |
五.session
5.1 使用:一定要加盐
1 | 设置值:session['user']='lqz' |
5.2 实例
1 | from flask import Flask, render_template, redirect, session, request, url_for |
5.3 session源码分析之wsgi_app
1. 流程分析
1 |
|
2. wsgi_app
1 | def wsgi_app(self, environ, start_response): |
5.4 session源码分析之:ctx = self.request_context(environ)
1 | """ |
1 | class RequestContext(object): |
5.5 session源码分析之:ctx.push()
1. ctx.push()
1 | """ |
1 | def push(self): |
2. open_session
1 | """ |
1 | def open_session(self, app, request): |
5.6 session源码分析之:response = self.full_dispatch_request()
1. full_dispatch_request
1 | """ |
1 | def full_dispatch_request(self): |
2. self.finalize_request(rv)
1 | """ |
1 | def finalize_request(self, rv, from_error_handler=False): |
3. response = self.process_response(response)
1 | """ |
1 | def process_response(self, response): |
4. save_session(self, ctx.session, response)
1 | """ |
1 | def save_session(self, app, session, response): |
六. 闪现(message)
6.1 作用
1 | 假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息 |
6.2 设置值
1 | 1. 普通设置 |
6.3 取值
1 | 1. 普通取值 |
6.4 实例
1 | from flask import Flask, url_for, flash, get_flashed_messages |
七. 请求拓展(类似于django中的中间件)
7.1 before_request
7.1.1 作用
1 | 类比django中间件中的process_request,在请求收到之前绑定一个函数做一些事情 |
1 | # 基于它做用户登录认证 |
7.2 after_request
7.2.1 作用
1 | 类比于django中间件中的process_response,每一个请求的之后绑定一个函数,如果请求没有异常。 |
1 |
|
7.3 before_first_request
7.3.1 作用
1 | 第一次请求时,和浏览器无关 |
1 |
|
7.4 teardown_request
7.4.1 作用
1 | 每一个请求之后绑定一个函数,即使遇到了异常 |
1 |
|
7.4.2 实例
1 | from flask import Flask, request, redirect, flash, get_flashed_messages |
1 | """ |
7.5 errorhandler
1 | 路径不存在时404,服务器内部错误500 |
1 |
|
7.5.1 实例
1 | from flask import Flask |
7.6 总结
1 | """ |
7.7 实例
7.7.1 实例一:before_request返回None
1 | from flask import Flask, request, redirect, flash, get_flashed_messages |
1 | """ |
7.7.2 实例二:before_request返回非None
1 |
|
1 | """ |
八. 中间件
8.1 作用
1 | """ |
8.2 源码分析
1 | """ |
8.3 如何自定义中间件
1 | from flask import Flask |
STEP-3
一. 蓝图(Blueprint)
1. 蓝图的作用
1 | """ |
2. 不使用蓝图自己分文件
2.1 目录结构
1 | D:. |
1 | """ |
2.2 manage.py
1 | from flask_test import app |
2.3 flask_test下的init.py
1 | from flask import Flask |
2.4 order.py
1 |
|
2.5 user.py
1 | def login(): |
2.6 views下面的init
1 | from .user import logout, login |
3. 使用蓝图之中小型项目
3.1 目录结构
1 | D:. |
1 | """ |
3.2 manage.py
1 | from flask_test import app |
3.3 flask_test下的init.py
1 | from flask import Flask |
3.4 order.py
1 | from flask import Blueprint |
3.5 user.py
1 | from flask import Blueprint |
3.6 views下面的init
1 | from .user import user_blue |
4. 使用蓝图之大型项目
4.1 项目目录
1 | D:. |
1 | """ |
4.2 manage.py
1 | from flask_app import app |
4.3 flask_app下面的init.py
1 | from flask import Flask |
4.4 flask_admin/flask_user下面的init.py
flask_admin
1 | from flask import Blueprint |
flask_user
1 | from flask import Blueprint |
4.5 views下面的init.py
flask_admin
1 | from .order import order |
flask_user
1 | from .order import order |
4.6 views下面的order.py
flask_admin
1 | from ...flask_admin import admin |
flask_user
1 | from ...flask_user import user_blue |
4.7 views下面的user.py
flask_admin
1 | from ...flask_admin import admin |
flask_user
1 | from flask_app.flask_user import user_blue |
5. 使用蓝图注意事项
5.1 当为templates目录添加目录解耦时
1 | render_template('user/login.html') |
6. 蓝图总结
1 | 总结: |
二. 请求上下文源码分析
1. Flask上下文的种类
1.1 应用上下文
1 | """ |
1.2 请求上下文
1 | """ |
2. 上下文的作用
1 | """ |
3. 上下文的生命周期
1 | """ |
4. 请求上下文环境构造
4.1 wsgi_app
1 | """ |
1 | def wsgi_app(self, environ, start_response): |
4.2 request_context
1.RequestContext的init方法
1 | class RequestContext(object): |
2. BaseRequest的init方法
1 | class BaseRequest(object): |
4.3 ctx.push
1.ctx.push
1 | def push(self): |
2. LocalStack的top方法
1 |
|
3.LocalStack的push方法
1 | def push(self, obj): |
4. Flask对象的app_context
1 |
|
5.AppContext的init方法
1 | class AppContext(object): |
6. open_session
1 | def open_session(self, app, request): |
4.4 full_dispatch_request
1. full_dispatch_request
1 |
|
2. try_trigger_before_first_request_functions
1 | def try_trigger_before_first_request_functions(self): |
3.preprocess_request
1 | def preprocess_request(self): |
4. dispatch_request
1 | def dispatch_request(self): |
5. finalize_request
1 | def finalize_request(self, rv, from_error_handler=False): |
6. process_response
1 | def process_response(self, response): |
7. save_session
1 |
|
4.5 RequestCentext类auto_pop
1. auto_pop
1 | def auto_pop(self, exc): |
2.RequestCentext类的pop方法
1 | def pop(self, exc=_sentinel): |
3. AppContext的pop
1 | def pop(self, exc=_sentinel): |
5. LocalStack
5.1 作用
1 | """ |
5.2 源码
1 | class LocalStack(object): |
6. Local
6.1 作用
1 | """ |
6.2 源码
1 | try: |
7. LocalProxy
7.1 作用
1 | """ |
1 | def _lookup_req_object(name): |
7.2 源码
1 |
|
8. g对象
8.1 作用
1 | """ |
8.2 g对象和session的区别
1 | """ |
8.3 实例
1 | from flask import Flask, g |
三. flask_session插件
1 作用
1 | 作用:将默认保存的签名cookie中的值 保存到 redis/memcached/file/Mongodb/SQLAlchemy |
2 安装
1 | 安装:pip3 install flask-session |
3 使用方式一
1 | from flask import Flask, request, session, g |
4 使用方式二
1 | from flask import g, Flask, session |
四. flask_script插件
1. 作用
1 | 用于实现类似于django中 python3 manage.py runserver ...类似的命令 |
2. 安装
1 | pip3 install flask-script |
3. 使用
1 | from flask import g, Flask, session |
1 | 以后在执行,直接:python3 文件名.py runserver |
五. 多app应用
1. 作用
1 | 用来分文件管理,管理不同的视图函数,蓝图就可以实现 |
2. 使用
1 | from werkzeug.wsgi import DispatcherMiddleware |
六. 信号
1. 作用
1 | Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为 。 |
2. 内置信号
1 | request_started = _signals.signal('request-started') # 请求到来前执行 |
3. 使用信号
1 | from flask import Flask, signals, render_template |
1 | """ |
4. Flask中信号的触发点
1 | """ |
5. 自定义信号(了解)
1 | from flask import Flask |
1 | """ |
STEP-4
一. wtforms组件
1. 安装
1 | """ |
2. 作用
1 | 1. 和django中的forms组件基本类似,可以参考django使用 |
3. 使用
1 | 1.前端传过来的数据,通过post或者get,或者body里面取出来,生成字典类型 |
4. 简单使用
4.0 使用步骤
1 | """ |
4.1 视图
1 | from flask import Flask, render_template, request |
4.2 模板
1 |
|
4.3 关闭html的form验证功能
1 | <form method="post" novalidate="false"> |
5. 复杂使用
5.1 视图
1 | from flask import Flask, render_template, request |
5.2 模板
1 |
|
二. Python中的数据库连接池DBUtils
1. 为什么要用数据库连接池
1 | 1. 所有请求用同一个连接,会造成数据不安全 |
1 | """ |
1.1 每个请求开个连接
1 | 缺点:会对数据库造成压力,且无法保证数据安全。 |
1 | from flask import Flask, render_template, request, redirect |
1.2 加锁使用单个数据库连接对象
1 | 缺点:无法支持并发 |
1 | # 第二步:缺点,不能支持并发 |
1.3 结论
1 | 由于上述原因,所以使用数据库连接池。每来一个请求从池中 取个连接,当连接取完过后,其他的请求在排队等待,当一个请求执行完毕后,将连接放回池中,供排队的请求使用 |
2. 什么是DBUtils
1 | DBUtils是Python的一个用于实现数据库连接池的模块 |
3. DBUtils的2种模式
3.1 模式一:PersistentDB
1 | 1. 提供线程专用的数据库连接,并自动管理连接。 |
1 | from DBUtils.PersistentDB import PersistentDB |
3.2 模式二:PooledDB
1 | 1. 提供线程间可共享的数据库连接,并自动管理连接。 |
1 | import pymysql |
三. SQLAlchemy模块
1. 什么是SQLAlchemy
1 | SQLAlchemy是一个基于Python实现的ORM框架。该框架建立在 DB API之上,使用关系对象映射进行数据库操作, |
2. 安装
1 | pip3 install sqlalchemy |
3. 组成
1 | """ |
4. 注意
4.1 SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件
4.2 Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作
1 | """ |
5. 简单使用
5.1 注意事项
1 | 1. 不能创建数据库 |
5.2 执行原生sql(不常用)
1 | import time |
5.3 orm使用
models.py
1 | import datetime |
app.py
1 | from sqlalchemy.orm import sessionmaker |
6. 单表操作
models.py
1 | import datetime |
app.py
1 | from sqlalchemy.orm import sessionmaker |
6.1 增
1.新增单条记录:add
1 | """ |
2. 新增多条记录:add_all
1 | """ |
6.2 改
1. 传字典:update
1 | """ |
2. 类似于django的F查询:update
1 | """ |
6.3 删
1. delete
1 | """ |
6.4 查
1.查所有-all
1 | """ |
2. filter过滤查询-all
1 | """ |
3. filter_by过滤查询-all
1 | """ |
4. filter和filter_by的区别
1 | filter传的是表达式,filter_ 传的是参数 |
5. first查询
1 | """ |
6. params查询
1 | """ |
7. 自定义查询sql
1 | """ |
7. orm一对多关系
7.1 关联字段写在多的地方
1 | import datetime |
8. 多对多关系
1 |
9. 单表查询
1 | 查询:********非常重要********** |
1 | 查询:基于双下划线的模糊查询 |
10.常用操作:增删改
10.1 插入数据
1 | Session = sessionmaker(bind=engine) # 获取 Session类 |
10.2 修改数据
1 | zhangsan = ses.query(Student).filter_by(name='zhangsan').first() #先获取对象 |
也可以在还创建数据的时候修改,就是在提交之前进行修改:
1 | liqi = Student(name="liqi", gender=1, std_id='XS335', teacher='xiadonghai', math=100) #实例化一个对象 |
在创建一个对象之后,未添加之前直接改变其属性。
1 | liqi = Student(name="liqi", gender=1, std_id='XS335', teacher='xiadonghai', math=100) |
除此之外还可以使用update。
1 | sess.query(Student).filter_by(name='liming').update({'gender':0}) |
10.3 删除数据
1 | result = sess.query(Student).filter(Student.id == 1 ).delete() |
11. 常用操作:查
11.1 算术操作符
1 | = 操作符 |
11.2 模糊查询
1 | like 操作符 % 代表任意多个字符 _ 代表一个字符 |
11.3 区间选取
1 | in 操作符 |
11.4 分页
1 | student_10 = sess.query(Student).limit(2).offset(1).all() #从第几条开始选取几条 |
11.5 排序
1 |
|
11.6 分组
1 | group_by 分组 |
11.7 having:分组之后条件过滤
1 | having |
11.8 计数
1 | count |
11.9 去重
1 | distinct |
11.10 空值
1 | 是否为null |
11.11 逻辑操作
1 | and |
11.12 text:原生sql语句
1 | text 原生sql条件语句 |
11.13 使用别名
1 | student_7 = sess.query(Student.name.label('std_name')).all() |
11.14 取值
1 | 根据主键获取对象 |
11.15 chain链式调用
1 | student_15 = sess.query(Student).filter_by(gender=1).filter(Student.math>80).all() |
12. 一对多的操作
1 | import time |
13. 多对多的操作
1 | import time |
14. 其他不常用操作
1 | import time |
四. Flask-sqlalchemy
1. 目录
1 | D:. |
2. init.py
1 | #!/usr/bin/env python |
3. models.py
1 | #!/usr/bin/env python |
4. settings.py
1 | #!/usr/bin/env python |
5. create_table.py
1 | #!/usr/bin/env python |
6. account.py
1 | #!/usr/bin/env python |
7. run.py
1 | #!/usr/bin/env python |