奇迹969

 

Flask 笔记


1.CBV 模式
	1.继承 views.MethodView
		from flask.views import MethodView
	
	2.HTTP具有 8 种请求方法 - CBV中的方法
	- GET 			获取
	- POST 			增加
	- DELETE 		删除
	- PUT 			更新
	- OPTIONS  		跨域请求
	- HEAD			?
	
	3.例子
		from flask import Flask
		from flask.views import MethodView
		app = Flask(__name__)
		class Login(MethodView):
			# decorators = []
			# methods = ["GET", "POST"]
			def get(self):
				pass
			def post(self):
				pass
		app.add_url_rule(rule="/login", endpoint=None, view_func=Login.as_view(name="login"))
		- 此处 Login.as_view(name="login") 其中的 name 所指定的即 endpoint 所指定的
		- 若 endpoint 不为 None 则 Login.as_view(name="login") 中指定的不会将其覆盖
		-- 见源码
			@setupmethod
			def add_url_rule(
				self,
				rule,
				endpoint=None,
				view_func=None,
				provide_automatic_options=None,
				**options
			):
				if endpoint is None:
					endpoint = _endpoint_from_view_func(view_func)
				options["endpoint"] = endpoint
			--- 此处  _endpoint_from_view_func(view_func) 见源码, 返回值为 view_func.__name__
				def _endpoint_from_view_func(view_func):
					assert view_func is not None, "expected view func if endpoint is not provided."
					return view_func.__name__
			综上, 若 endpoint 不等于 None 则直接使用 endpoint 参数被赋予的值 options["endpoint"] = endpoint
	
	4.创建API建议使用CBV模式
	
2.串讲 Flask
	1.Flask优势:
	- 轻量级框架, 扩展性强, 三方组件齐全
	2.Flask劣势:
	- 过简, 只有 session 组件, 其他组件是第三方的, 稳定性相对较差
	3.安装
		pip3 install Flask
	4.依赖包
	- Jinja2		模板语言
	- Flask		源码
	- MarkupSafe	处理标签语言
	- Werkzeug	封装 WSGI 的工具包, 承载 Flask 程序
	-- - app.run() 本质上是执行run_simple() 见源码
			def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
				...
				from werkzeug.serving import run_simple
					try:
						run_simple(host, port, self, **options)
					finally:
						self._got_first_request = False
	
	5.启动
		from flask import Flask
		app = Flask(__name__)
		app.run("0.0.0.0", 9527)
		- 0.0.0.0 监听当前机器所有 IP
	6.路由视图
		@app.route(rlue="/index", methods=["GET", "POST"], endpoint="index")
		def index():
			return "Hello"
		- endpoint	做 Mapping 使用 -> "/index": {"index": index}
		-- 可通过 url_for("endpoint_value") 进行反向解析, 得到 rule_value
		- methods 	当前路由允许的请求方式
		-- methods 默认为("GET",)
		
	7.FlaskResponse
	- render_template()
	- redirect("")
	- HttpResponse
	-- [String, List, Tuple, Dict]
	--- return "String"
	--- return  [String, List, Tuple, Dict]
	--- return (String, List, Tuple, Dict
	--- return {key: value}	- Flask-1.1.1 新特性, 可以直接返回 dict 类型 - 本质上就是 jsonify
	
	* jsonify
		** Response Heads 中 Content-Type:application/json 
		** Flask-1.1.1 新特性, 可以直接返回 dict 类型 - 本质上就是 jsonify
	* send_file	打开并返回文件内容, 自动识别文件类型 Content-Type:文件类型
		** 无法识别的文件类型触发下载(浏览器实现)
	
	8.FlaskRequest
	- from flask import request	公共变量 LocalProxy 对象
	------ Django -------	==	----- Flask ---------------------
	-- request.POST.get() 	== 	request.form.get() -> .to_dict()	| 获取FormData中的参数
	-- request.GET.get()		== 	request.args.get() -> .to_dict()	| 获取URL中的参数
	-- 							request.files.get()				| 获取文件
	-- 							request.method					| 获取请求方式
	-- 							request.path					| 获取路由地址
	-- 							request.url						| 获取访问路径
	-- 							request.host					| 获取服务器地址 127.0.0.1:9000
	-- 							request.host_url				| 获取完整的服务器地址 http://127.0.0.1:9000
	--							request.json					| Content-Type:application/json 的请求数据
	--							request.data					| Content-Type 无法被识别, 或者是没有 form 的请求数据
	
	9.session
		from flask import session
		app = Flask(__name__)
		app.secret_key = "!@#$%^&*()"
		- 使用 session 必须设置 secret_key 否则报错
		...
		session["key"] = value
		...
		- 存储在 Cookies 中
		- 序列化 - {key: value} -> secret_key + 时间戳 + 签名 -> 生成 String -> SESSION_COOKIE_NAME:String
		- 反序列化 - SESSION_COOKIE_NAME:String -> secret_key + 时间戳 + 签名 -> {key: value}
	
	10.配置
		1.初始化配置 - app = Flask(__name__)
		- template_folder
		- static_folder
		- static_url_path
		2.confing	Flask 对象配置
		Flask.default_config	获取默认配置
		------------------------- 区别 ---------------------------------------------
		- DEBUG					log级别()		编码阶段热加载	错误信息透传
		- TESTING				log级别()
		----------------------------------------------------------------------------
		- SESSION_COOKIE_NAME
		- SECRET_KEY
		
		* Flask.config.from_obj()
			class DebugSettings(object):
				DEBUG = True
				SECRET_KEY = "!@#$%^&*()"
				SESSION_COOKIE_NAME = "SESSION"
			Flask.config.from_obj(DebugSettings)
			# Flask.config["DEBUG"] = True
		
	11.蓝图
	- 应用隔离
	- 不能被 run 的 Flask 实例, 没有 config
		from flask import Buleprint
		userBP = Blueprint("bpname", __name__, url_prefix="/user")
		@userBP.route("/userBP")
		def user_bp():
			return "Hello"
		-- 思考: 如何在蓝图中使用 CBV 模式

	12.特殊装饰器
		1.before_request					请求进入视图函数之前
		2.after_request						结束视图函数之后, 倩影客户端之前
		3.errorhandler(HTTP_ERROR_CODE)		重定义错误信息
		-- HTTP_ERROR_CODE: [5XX, 4XX]
		- before_request + after_request 实现中间件
		-- 正常周期: beforefunc1 -> beforefunc2 -> viewfunc -> afterfunc2 -> afterfunc1
		-- 异常周期: beforefunc1 -> afterfunc2 -> afterfunc1
		
	13.CBV
		from flask.views import MethodView
		class Login(MethodView):
			methods = []
			def get(self)
				pass
			def post(self)
				pass
			...
			-- 满足 HTTP 协议的 8 种请求
		Flask.add_url_rule(rule="/login", endpoint=None, view_func=Login.as_view(name="login"))

3.Flask-Session
- 第三方组件
- def save_session	序列化
- def open_session	反序列化
- 所有的 Flask 第三方组件都需要 Flask.config 不但要吸取配置项, 还会更改或者增加配置项
	
	from flask import Flask
	from flask_session import Session
	app = Flask(__name__)
	app.config["SESSION_TYPE"] = "redis"
	app.config["SESSION_REDIS"] = Redis(host="127.0.0.1", port=6379, db=0)Session(app)
	- 初始化
	-- Flask-Session - 读取 config 配置, 改写 app 中的 session_interface
	! 此处存在一个问题
	!!  注意 Session(app)
		未进行配置 app.config["SESSION_TYPE"] 时其默认值为 "null" 将使用 NullSessionInterface , 在使用 session 过程中将会产生报错信息
			RuntimeError: The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
		> 原因
			NullSessionInterface
				If you do not configure a different SESSION_TYPE, this will be used to generate nicer error messages. Will allow read-only access to the empty session but fail on setting.
		>> 翻译
			如果您没有配置不同的 SESSION_TYPE 这将用于生成更好的错误消息. 将允许只读访问空会话但设置失败
	Python 操作 redis
	- redis 不要暴露到外网中, 要放到内网服务器中 redis 有无法修复的 bug 易受到攻击
		from redis import Redis
		r = Redis(host="127.0.0.1", port=6379, db=0)
		- db 默认等于 0 
		-- select 用于数据隔离, 最高可设置 16 个(0-15), 作用于 db


待补充
	- Flask-CORS				解决跨域
	- Flask-WTF				表单(类似 Django 中的 Form 组件)
	- Flask-SQLAlchemy		ORM
	- Flask的request.form和request.data有什么区别?
	-- 首先使用这两个方法的前提是 POST 或者 PUT 请求两者的区别在于处理不同 mimetype 类型的数据, 返回值也不同. 当 minitype 为 application/x-www-form-urlencoded 或者 multipart/form-data 的时候, 也就是我们所谓表单提交, 访问request.form 会返回一个包含解析完成的表单对象的 MultiDict , 而 request.data 是空的. 当 flask 遇到不能处理的 mimetype 时, 请求的数据就不能被其它方式正常解析, 这些方式包括 request.form, request.json 和 request.files 这几个常用的用来访问数据的属性. 这时就把数据作为字符串存在 request.data 中. 这里注意一下 request.json 需要application/json 的 mimetype 类型. 知道了这些处理数据的过程, 那我们就可以对提交的数据进行扩展, 定义一些自己专用的 mimetype 类型, 并在 Request 类中定义处理专用 mimetype 数据的方法, 从而让我们实现更个性, 与众不同的功能需求 -- 知乎用户 - 付楠
	








蓝图 CBV
from flask import Blueprint,request,render_template,session,redirect,views

login2 = Blueprint("login", __name__,template_folder="../template")   #login2 为实例化下面  添加路径    .add_url_rule 处用    ////      “login”为蓝图name 存储路径    

# @login2.route('/',methods=["post","get"])
#注意 蓝图名字和视图函数的名字不能一样
# def login1():
#     if request.method == 'GET':
#         return  render_template("login.html")
#
#     if request.form.to_dict().get("username")=="123" and request.form.to_dict().get("pwd")=="123":
#         session["username"]="JWB"
#         session["pwd"] = "DSB"
#         print(session.keys())
#         return redirect('/summary')
#     return render_template("login.html")

class Login1(views.MethodView):
    def get(self):
          return  render_template("login.html")

    def post(self):
        if request.form.to_dict().get("username")=="123" and request.form.to_dict().get("pwd")=="123":
            session["username"]="JWB"
            session["pwd"] = "DSB"
            print(session.keys())
            return redirect('/summary')
        return redirect("login.html")






login2.add_url_rule('/', view_func=Login1.as_view(name='login'))       #  as_view(name="")相当于endpoint

 

FLASK--Session

from flask_session import  Session
from redis import Redis

app = Flask(__name__,template_folder="template")
app.config["SESSION_TYPE"] = "redis"
app.config["SESSION_REDIS"] = Redis(host="127.0.0.1",port=6379,db=1)
# app.secret_key = "#$%^&*#$%^&#$%2213123^&"
# app.config.from_object(DebugSetting)
# app.config.from_object(TesingSetting)

Session(app)



#取session 键为session:session_id redis : keys * 查看所有的键

 




posted on 2019-07-12 17:04  奇迹969  阅读(259)  评论(0编辑  收藏  举报

导航