CBV源码闪现请求扩展蓝图g对象flask-session

路由常见写法

@app.route('/index', methods=['GET'], endpoint='index')
def index():
    return 'hello'

默认转换器

'default':          UnicodeConverter,
'string':           UnicodeConverter,
'any':              AnyConverter,
'path':             PathConverter,
'int':              IntegerConverter,
'float':            FloatConverter,
'uuid':             UUIDConverter,   

路由的本质

1.通过源码分析发现route的内层函数是self.add_url_role(rule,edpoint,f,**options)
2.self是当前app对象也就是路由的本质就是app.add_url_role('/index',view_func=index函数)

CBV源码

from flask.views import MethodView
1.写法app.add_url_role('/index',view_func=类.as_view(name='别名且不能冲突'))
2.可以发现as_view()最后返回的是个view的内存地址,请求来了会执行dispath_request(),MethodView重写了dispatch_request()然后也是根据请求方式执行同名的方法
3.一般视图是继承MethodView,而继承View要重写dispatch_request
4.根据源码分析FBV如果不写别名,会默认将函数名作为别名
5.CBV添加装饰器写个类属性
  decorators=(装饰器1,装饰器2)  # 元组前面的装饰器在装饰器最下面
6.CBV控制访问请求写个属性
  methods=['get','post']

add_url_rule参数分析

1.rule:请求的路径,可以使用转化器,用了转换器匹配对应的类型且转换类型
2.endpoint:别名用于反向解析
3.view_func:视图函数的内存地址/类.as_view(name='xxx')
4.methods:允许的请求方式
#其他了解
defaults:字典,作用可以给视图函数传递默认值
strict_slanshes:对url最后的符号是否严格要求
redirect_to:不执行当前函数,直接就是重定向到redirect_to指定的路由

模板

1.模板一般使用的jnjia2与dtl不同,对应字典可以以[],和.get('xx')取值,函数也能直接夹括号得到结果
2.内部处理了xss攻击,原来就是利用了html的特殊字符替换
3.或者直接使用|safe,就会将html字符串渲染

请求响应

from flask import Flask, request,make_response,render_template
# request内的方法
 print(request.method) # 请求方式
    print(request.args) # get 请求参数
    print(request.form) # post提交的数据
    print(request.values)  # get,post提交的数据总和

    print(request.cookies)  # cookies
    print(request.headers)  # 请求头
    print(request.path)  # 路径
    print(request.full_path)  # 全路径
    print('-----',request.script_root)
    print(request.url)      # 带服务器地址的全路径
    print(request.base_url)  # 不带地址的全路径
    print(request.url_root)   # 域名+端口
    print(request.host_url)  # 域名+端口
    print(request.host)    # 不带http的域名+端口
    from werkzeug.datastructures import FileStorage
    print(type(request.files.get('files')))

2.make_reponse包裹四件套
 res=make_response(render_template('home.html'))
 res.set_cookie('name','lqz')
3.响应头加数据
 res=make_response(render_template('home.html'))
 res.headers['X-Something'] = 'A value'

session源码分析

1.app.session_interface--->secureCookieSessionInterface()类的对象
  两个重要方法:
     open_session:请求来了,取出cookie中的字符串,把字符串反序列化成session对象
     save_session:请求走,把session对象,序列化成字符串,放到cookie中

闪现

app.secret_key = 'asdfasdfae4342@@4353' # 依赖session
# flash作用:
    这次请求的信息放在flash空间中,能在后面取一次flash空间就会销毁
# 使用
设置值:flash(err)
       flash(err,category='xx类')
取值:导入get_flashed_messages
如果没有分类直接这个函数get_flashed_messages()结果就是上次设置的值
有分类err = get_flashed_messages(category_filter=['lqz'])以名取,设置的值取不取下次请求都拿不到了
# 等同于django中的message框架

请求扩展

# 类似django中的中间件
 1. before_reuqest  # 对应这django中的process_request
    -return四件套,不继续往下走了,如果retrun None,继续走下一个请求扩展
	-请求来了,就会执行它
    -# 重点多个before_request,会从上往下依次执行
 2.after_request    # 对应这django中的process_response
	-必须返回response对象
    -请求走了,会执行它
    -# 重点多个after_request,从下往上依次执行
 3.before_first_request
    -项目启动后,第一次访问,会执行
    -返回None,会继续往下执行,返回四件套,就不继续往后走了
 	-无论程序是否出异常,都会触发它
    -记录错误日志
    -app.debug=False模式才行
 4.teardown_request
    -无论程序是否出异常,都会触发它
    -记录错误日志
    -app.debug=False模式才行
 5.errorhandler
	-监听某个状态码,如果是这个状态码的错误,就会触发它的执行
    -可以返回四件套,统一返回格式

# template_global:标签
	# 定义
	@app.template_global()
        def sb(a1, a2):
            return a1 + a2
    # 模板中使用
    {{sb(1,2)}}
# template_filter:过滤器
    # 定义
        @app.template_filter()
        def db(a1, a2, a3):
            return a1 + a2 + a3
    # 模板中使用
    {{ 1|db(2,3)}}

蓝图

# Blue_print:就是目录结构
蓝图的使用:
	1 实例化得到蓝图对象 ---可以传一些参数:account = Blueprint('account', __name__,templates,static)
    2 把蓝图对象在app中注册---》app.register_blueprint(account,制定前缀)
    3 使用蓝图对象,注册路由
    4 蓝图有自己的请求扩展--》app对象总的请求扩展,每个蓝图有自己的请求扩展
# 小项目设定目录
 -flask_pro               #项目名
            -pro_flask          # 文件夹
                -__init__.py    # 包的init文件
                -static          #静态文件
                	-code.png
                -templates       #模板文件
                	-index.html
                -views           #视图函数写在里面
                    -account.py    #订单相关视图函数
                    -user.py     #用户相关视图函数
                    -blog.py     #博客相关视图函数
             -manage.py          # 项目的启动文件
 

pro_flask/init.py

from flask import Flask

app = Flask(__name__,template_folder='templates',static_folder='statics',static_url_path='/static')

from .views.account import account
from .views.blog import blog

# 注册3个蓝图,把他们注册进app中
app.register_blueprint(account)
app.register_blueprint(blog)

pro_flask/views/account.py

from flask import Blueprint
from flask import render_template
# 实例化得到蓝图对象
account = Blueprint('account', __name__)

@account.route('/login.html', methods=['GET', "POST"])
def login():
    return render_template('login.html')

pro_flask/views/blog.py

from flask import Blueprint, render_template,request

blog = Blueprint('blog', __name__)

@blog.route('/get_blog')
def get_blog():
    print(request.path)
    return render_template('blog.html')

manage.py

from pro_flask import app
if __name__ == '__main__':
    app.run()

多个app

pro_flask   # 项目名
    -pro_flask #包名
        -admin #admin  app的名字
            -static #app自己的静态文件
            -templates #app自己的模板文件
            -__init__.py #包的init
            -views.py   #app自己的视图函数
        -web  #web   app的名字
            -static  #app自己的静态文件
            -templates #app自己的模板文件
            -__init__.py #包的init
            -views.py  #app自己的视图函数
        -__init__.py
    -run.py

pro_flask/admin/init.py

from flask import Blueprint

# 第一步:初始化蓝图
admin = Blueprint(
    'admin',
    __name__,
    template_folder='templates',  # 指定该蓝图对象自己的模板文件路径
    static_folder='static'       # 指定该蓝图对象自己的静态文件路径
)


from . import views

pro_flask/admin/views.py

from . import admin
from flask import render_template
@admin.before_request
def before():
    print('admin 的 before')
# 第三步:使用蓝图注册路由
@admin.route('/index')
def index():
    return render_template('admin.html')

pro_flask/web/init.py

from flask import Blueprint
web = Blueprint(
    'web',
    __name__,
    template_folder='templates',
    static_folder='static'
)
from . import views

pro_flask/web/views.py

from . import web
@web.route('/index')
def index():
    return 'Web.Index'

pro_flask/init.py

from flask import Flask
from .admin import admin
from .web import web

app = Flask(__name__)
app.debug = True

# 第二步:在app中注册蓝图
app.register_blueprint(admin, url_prefix='/admin') # url_prefix='/admin' 访问这个app的前缀,等同于include
app.register_blueprint(web)


run.py

from pro_flask import app

if __name__ == '__main__':
    app.run()

g对象

# g对象其实是为globla关键之,所以写成了魔鬼变量
# 作用就是针对当此请求做一个传值的功能,放值和取值
# 用法
from flask import Flask, g, request,session
app = Flask(__name__)
app.debug=True
@app.before_request
def before():
    print(type(g))  # werkzeug.local.LocalProxy    代理模式
    print(type(session))
    print(type(request))
    if request.path == '/':
        # request.method='lqz'
        g.name = 'lqz'  # 放到g对象中
    else:
        # request.name = 'pyy'
        g.name = 'pyy'
def add(a,b):
    print(g.name)
    # print('-----', request.name)
@app.route('/')
def index():
    print(g.name)
    # print('-----',request.name)
    # add(1,2)
    return 'hello'
@app.route('/home')
def home():
    print(g.name)
    return 'hello'
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

flask-session的使用

# 更改自带的session存放位置
  写一个类,写open_session和save_session方法
# 直接使用flask-session第三方支持
  from flask_session import RedisSessionInterface
  app.session_interface=RedisSessionInterface(redis=None,key_prefix='luffy_'(sessionkey自带前缀))
# 通用方案
from redis import Redis
from flask_session import Session
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_KEY_PREFIX'] = 'luffy'  # 相当于app.secret_key='a'加session头
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
Session(app)  #后面会经常见这种写法--->类(app)---》包一下的写法

posted on 2022-08-09 17:58  淦白嫖怪  阅读(52)  评论(0)    收藏  举报

导航