Flask
导入
from flask import (
Flask,request,render_template,redirect,session,url_for,Markup,make_response,views,jsonify,
flash,get_flashed_messages,
)
request # 传过来的请求
render_template # 模板
redirect # 重定向,可配合url_for
url_for # 反向解析
session # 使用前要先设置密钥:app.secret_key=''
Markup # 处理XSS攻击
make_response # 制作响应对象
views # CBV继承views.MethodView
flash # 闪现设值
get_flashed_messages # 闪现取值
route和dtl
# 路由
# @app.route和app.add_url_rule参数
strict_slashes=False # 对url最后的 / 是否做严格要求,默认严格
redirect_to='login/' # 重定向到指定地址
methods=['GET', 'POST', ] # 支持的请求方式
endpoint='login' # 别名,如果不写默认是函数名,并且不能重名
subdomain = None # 子域名访问
# 路由的本质就是:app.add_url_rule()
# 模板语言渲染同dtl,但比dtl更加强大,支持函数加括号执行,字典支持点取值、括号取值和get取值
配置文件
# 配置方式
1.app.config['DEBUG'] = True # debug为True可能会无效,edit configurations-->勾选FLASK_DEBUG
2.通过文件配置
app.config.from_pyfile("settings.py")
app.config.from_json("settings.json")
3.类(常用)
app.config.from_object('settings.DevelopmentConfig')
settings.py
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
PS: 从sys.path中已经存在路径开始写
PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录(Flask对象init方法的参数)
# 配置
flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
{
'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,
}
转换器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
@app.route('/detail/<int:pk>', methods=['GET'])
CBV
"""示例"""
def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result
return inner
class IndexView(views.MethodView):
methods = ['GET', 'POST'] # 指定允许的请求方法
decorators = [auth, ] # 认证函数,加多个就是从上往下的效果
def get(self):
return "我是get请求"
def post(self):
return '我是post请求'
app.add_url_rule('/index/', view_func=IndexView.as_view('index')) # 路由注册
请求和响应
"""请求"""
print(request.method) # 提交的方法
print(request.args) # get请求提及的数据
print(request.form) # post请求提交的数据
print(request.values) # post和get提交的数据总和
print(request.values.getlist('name')) # get和list的key一样是要用getlist
print(request.cookies) # 客户端所带的cookie
print(request.headers) # 请求头
print(request.path) # 不带域名,不带参数请求路径
print(request.full_path) # 不带域名,带参数的请求路径
print(request.url) # 带域名带参数的请求路径
print(request.base_url) # 带域名请求路径
print(request.url_root) # 带域名请求路径
print(request.host_url) # 带域名请求路径
print(request.host) # 127.0.0.1:5000
print(request.files) # 上传的文件
"""响应"""
# return "字符串"
# return render_template('html模板路径',**{})
# return redirect('/index/')
# return jsonify({'key':'v'})
res = make_response() # 制作响应对象
res.set_cookie('key', 'v')
res.headers['X-Token'] = ''
res.delete_cookie('key')
闪现
flash('') # 设置值,可以加category参数
get_flashed_message() # 取值,取出分类category_filter=['', '']
# 原理
把值放到了session中
# 应用场景
假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息
请求扩展
# 类似于django的中间件
@app.before_request:请求来的时候执行,类似于Django的process_request,多个是从上往下执行
@app.after_request:请求走的时候执行,类似于Django的process_response,多个是从下往上执行
@app.before_first_request:项目第一次启动来请求时执行,只执行一次,也可以配多个
@app.teardown_request:每次视图函数执行完都会执行,即使报错也会执行,可用来记录日志
@app.errorhandler(404):绑定错误的状态码,只要码匹配,就执行
@app.template_global:全局标签
@app.template_filter:全局过滤器
# before_request请求拦截后(也就是有return值),所有的after_request(response)都会执行,Django中请求拦截后,从当前位置拦截响应回去
# 示例
@app.before_request
def before():
print('before')
@app.after_request
def after(response):
print('after')
return response
@app.before_first_request
def first():
print('first')
@app.teardown_request
def teardown(*args, **kwargs):
# print('teardown', args)
# print('teardown', kwargs)
print('teardown')
@app.errorhandler(404)
def error_404(*args, **kwargs):
print('errorhandler404', args)
# print('errorhandler404', kwargs)
return render_template('errors.html', message=args[0])
@app.template_global()
def a(a1, a2):
return a1 + a2
@app.template_filter()
def b(a1, a2, a3):
return a1 + a2 + a3
# errors.html
<h3>{{ message }}</h3>
{{ a(1,2) }}
{{ 1|b(2,3) }}
中间件
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
# 模拟中间件
class Md(object):
def __init__(self,old_wsgi_app):
self.old_wsgi_app = old_wsgi_app
def __call__(self, environ, start_response):
print('开始之前')
ret = self.old_wsgi_app(environ, start_response)
print('结束之后')
return ret
if __name__ == '__main__':
#1我们发现当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行app.__call__方法
#2 在__call__里面,执行的是self.wsgi_app().那我们希望在执行他本身的wsgi之前做点事情。
#3 所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
#4 那执行新的的app.wsgi_app,就是执行Md的__call__方法。
#把原来的wsgi_app替换为自定义的,
app.wsgi_app = Md(app.wsgi_app)
app.run()
猴子补丁
# 什么是猴子补丁?
# 只是一个概念,不属于任何包和模块
# 利用了python一切皆对象的理念,在程序运行过程中,动态修改方法
# 有什么用?
# 这里有一个比较实用的例子,
# 很多用到import json,
# 后来发现ujson性能更高,
# 如果觉得把每个文件的import json改成import ujson as json成本较高,
# 或者说想测试一下ujson替换是否符合预期, 只需要在入口加上:
# 只需要在程序入口
# import json
# import ujson
# def monkey_patch_json():
# json.__name__ = 'ujson'
# json.dumps = ujson.dumps
# json.loads = ujson.loads
# monkey_patch_json()
# 以后用的json操作就是ujson
蓝图
# 使用
1.在app中注册蓝图,括号里是一个蓝图对象
app.register_blueprint(user.account)
2.第二步,在不同文件中注册路由时,直接使用蓝图对象注册,不用使用app了,避免了循环导入的问题
from flask import Blueprint
account = Blueprint('user', __name__, url_prefix='/xxx', template_folder='xxx')
# url_prefix:给当前蓝图下的url都加上统一的前缀
# template_folder:每个蓝图可以设置自己的templates
3.写视图
@account.route('/login.html', methods=['GET', "POST"])
# 蓝图的befort_request,只对当前蓝图有效
session源码的执行流程
# save_seesion
-响应的时候,把session中的值加密序列化放到了cookie中,返回到浏览器中
# open_session
-请求来了,从cookie中取出值,反解,生成session对象,以后再视图函数中直接用sessoin就可以了。
标签:__,知识点,return,Flask,app,request,print,def
From: https://www.cnblogs.com/hkwJsxl/p/17128225.html