Flask框架深入一

Flask框架深入一

1、函数加装饰器执行的顺序

# flask的路由基于装饰器----》在视图函数上再加装饰器---》加多个装饰器的执行顺序---》登
# 录认证装饰器---》加载router下,先做路由匹配,匹配成功执行被auth包裹的视图函数

2、路由系统

@app.router('/',menthods=['GET','POST']) ==> app.add_url_rule(rule='/',endpoint='index',view_func=index,methods=['GET'])
# flask的路由是基于装饰器的---》但是它的本质是app.add_url_rule方法--->类似于django 的path(url)
1、路由系统本质
"""
# route的源代码
1. decorator = app.route('/',methods=['GET','POST'],endpoint='n1')
    def route(self, rule, **options):
        def decorator(f):
            endpoint = options.pop('endpoint', None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f
        return decorator
2. @decorator
   decorator(index)----》本质---》self.add_url_rule(rule, endpoint, f, **options)
   
   
3 路由的本质可以写成
app.add_url_rule(rule='/',endpoint='index',view_func=index,methods=['GET'])


4 (了解)endpoint如果不传,是None,也有个默认值---》函数的名字
	-如果使用了装饰器,一定要指定endpoint
"""
2、转换器
app.add_url_rule(rule='/index/<string:name>',endpoint='index',view_func=index,methods=['GET'])

# 跟django 2.x后的转换器一样
DEFAULT_CONVERTERS = {
    'default':          UnicodeConverter,
    'string':           UnicodeConverter,
    'any':              AnyConverter,
    'path':             PathConverter,
    'int':              IntegerConverter,
    'float':            FloatConverter,
    'uuid':             UUIDConverter,
}
3、app.add_url_rule参数
@app.route和app.add_url_rule参数:
#1   rule, URL规则
#2  view_func, 视图函数内存地址
#3  defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}   为函数提供参数
#4 endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
#5 methods = None, 允许的请求方式,如:["GET", "POST"]
#6 对URL最后的 / 符号是否严格要求
	strict_slashes = None
    '''
        @app.route('/index', strict_slashes=False)
        #访问http://www.xx.com/index/ 或http://www.xx.com/index均可
        @app.route('/index', strict_slashes=True)
        #仅访问http://www.xx.com/index
    '''
#7 重定向到指定地址
redirect_to = None, 
    '''
        @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
    '''
4、支持正则(不用)
#1 写类,继承BaseConverter
#2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>')  正则表达式会当作第二个参数传递到类中
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter

app = Flask(import_name=__name__)

class RegexConverter(BaseConverter):
    """
    自定义URL匹配正则表达式
    """
    def __init__(self, map, regex):
        super(RegexConverter, self).__init__(map)
        self.regex = regex

    def to_python(self, value):
        """
        路由匹配时,匹配成功后传递给视图函数中参数的值
        """
        return int(value)

    def to_url(self, value):
        """
        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
        """
        val = super(RegexConverter, self).to_url(value)
        return val
# 添加到flask中
app.url_map.converters['regex'] = RegexConverter
@app.route('/index/<regex("\d+"):nid>')
def index(nid):
    print(url_for('index', nid='888'))
    return 'Index'

if __name__ == '__main__':
    app.run()
5、CBV源码分析(跟djagno没有区别)
from flask import Flask, url_for
from flask.views import View, MethodView

app = Flask(__name__)

app.debug = True  # 热更新---->不停机更新


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


# 1 写一个类,继承MethodView
class LoginView(MethodView):
    def get(self):
        return 'get --login'

    def post(self):
        return 'post---login'


# 2 配置路由,LoginView.as_view()但是必须带一个参数,参数是这个地址的别名

app.add_url_rule('/login', view_func=LoginView.as_view('login'))

# add_url_rule--->等同于django的pathpaht('/',index,name='index')
if __name__ == '__main__':
    app.run()

3、模板语法

# 完全兼容DTL,比DTL强大一些,可直接执行函数,还可以传参数
#1.Markup等价django的mark_safe ,
# 2.extends,include一模一样

4、请求与响应

# request对象属性和方法
	# request.method  提交的方法
    # request.args  get请求提及的数据
    # request.form   post请求提交的数据
    # request.values  post和get提交的数据总和(一般不用)
    # request.cookies  客户端所带的cookie
    # request.headers  请求头
    # request.path     不带域名,请求路径 http://127.0.0.1:5000/test_if?name=lqz&age=10----》/test_if
    # request.full_path  不带域名,带参数的请求路径--->/test_if?name=lqz&age=10
    # request.url           带域名带参数的请求路径-->最完整的路径
    # request.base_url		带域名请求路径
    # request.url_root      域名
    # request.host_url		域名
    # request.host			127.0.0.1:500
    # request.files         # 客户端上传的问题
    # obj = request.files['the_file_name']
# response对象
	######新手四件套
	# return "字符串"
    # return render_template('html模板路径',**{})
    # return redirect('/index.html')
    # return jsonify({'k1':'v1'})
    
	# 向cookie中写值
    # response = make_response(render_template('index.html'))
    # response是flask.wrappers.Response类型
    # response.delete_cookie('key')
    # response.set_cookie('key', 'value')
    # response.headers['X-Something'] = 'A value'
    # return response

5、session

# 通过全局的session
	-设置值:session['key']=value
    -取值:session['key']
    -删除值:del session['key']
    -不用管不同的用户,统一都用全局session取,不会乱
    
    
# 一部分源码解读(等同于django中的中间件django.contrib.sessions.middleware.SessionMiddleware)
	-这样设置session['key']=value---》在请求走的时候把这个数据,加密,放到cookie中给了前端
    -前端带着cookie再一次请求---》请求来的时候,反解出数据,再放到session中,这样你才能使用session['key']
    
    
    -SecureCookieSessionInterface---》负责干上面那俩事
    	--save_session:走的时候
    	--open_session:带着cookie来的时候

6、闪现

# flash 翻译过来的,flash函数
# 作用: 把一些数据放在某个位置,下次要用的时候,直接取出来,取一次就没了,下次请求再取就没了---》可以跨请求

# 放
flash('一坨大便')
# 分类放
flash('一个包子',category='bz')
flash('一个大便',category='db')
flash('又一个大便',category='db')
# 取
res = get_flashed_messages()
#分类取
res = get_flashed_messages(category_filter=['db'])


# 应用场景:在上一次的请求中有些数据,需要带到下次请求中看,就可以使用闪现

# 其实是放在session中等同于  session[ss]='sdsd'



# django也有类似的东西----》message这个app,就是它

7、请求扩展

# 类似于django的中间件,在请求来之前,和走之后执行一些方法
1、before_request

类比django中间件中的process_request,在请求收到之前绑定一个函数做一些事情

#基于它做用户登录认证
@app.before_request
def process_request(*args,**kwargs):
    if request.path == '/login':
        return None
    user = session.get('user_info')
    if user:
        return None
    return redirect('/login')
2、after_request

类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常

@app.after_request
def process_response1(response):
    print('process_response1 走了')
    return response
3、before_first_request

第一次请求时,跟浏览器无关

@app.before_first_request
def first():
    pass
4、teardown_request

每一个请求之后绑定一个函数,即使遇到了异常

@app.teardown_request 
def ter(e):
    pass
5、errorhandler

路径不存在时404,服务器内部错误500

@app.errorhandler(404)
def error_404(arg):
    return "404错误了"
6、template_global

标签

@app.template_global()
def sb(a1, a2):
    return a1 + a2
#{{sb(1,2)}}
7、template_filter

过滤器

@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3
#{{ 1|db(2,3)}}
总结:

1 重点掌握before_request和after_request,
2 注意有多个的情况,执行顺序
3 before_request请求拦截后(也就是有return值),response所有都执行

8、蓝图

# blueprint翻译过来的---》蓝图---》划分目录
# 不使用蓝图划分目录,也可以,但是会出现循环导入
# 使用蓝图可以避免

# 使用蓝图:
	1 创建蓝图对象blog = Blueprint('blog', __name__),可以使用自己的静态文件和template
    2 以后路由都使用蓝图对象来注册
    3 把所有蓝图在app中注册一下,可以指定前缀
    app.register_blueprint(blog)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值