Flask.源码.blueprints.py

该模块实现了Flask的蓝图,最主要的是定义了BlueprintSetupState和Blueprint类,实现了和路由相关的一些方法,但实质都是调用的app.py中Flask类中的方法。

class BlueprintSetupState(object):
	def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
	        if self.url_prefix:  #给url加上前缀
	            rule = self.url_prefix + rule
	        options.setdefault('subdomain', self.subdomain)
	        if endpoint is None:    #返回视图函数的名字 endpoint =view_func.__name__
	            endpoint = _endpoint_from_view_func(view_func)#返回视图函数的名字
	        defaults = self.url_defaults
	        if 'defaults' in options:
	            defaults = dict(defaults, **options.pop('defaults'))
	            #这里实质还是调用了app的add_url_rule
	        self.app.add_url_rule(rule, '%s.%s' % (self.blueprint.name, endpoint),
	                              view_func, defaults=defaults, **options)

为了便于理解,我改变了源码中定义函数的顺序。

class Blueprint(_PackageBoundObject):
"""通过@blueprint.route这个带参数的装饰器定义路由的时候,装饰器通过
    endpoint = options.pop("endpoint", f.__name__)语句找到了endpoint"""

    def route(self, rule, **options): #把视图函数添加到蓝图中,实质是调用add_url_rule
	    def decorator(f):   
	        endpoint = options.pop("endpoint", f.__name__)
	        self.add_url_rule(rule, endpoint, f, **options)
	        return f
	    return decorator
	    
    def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
	    if endpoint:
	        assert '.' not in endpoint, "Blueprint endpoint's should not contain dot's"
	    self.record(lambda s: s.add_url_rule(rule, endpoint, view_func, **options))
    #最后一句话很重要:这里调用了record,并以一个匿名函数当做参数,该匿名函数又包含了rule, endpoint, view_func, **options等信息,即对应一个视图函数。
    
    def record(self, func): 
		if self._got_registered_once and self.warn_on_modifications:
	         from warnings import warn
	         warn(Warning('The blueprint was already registered once '
                      'but is getting modified now.  These changes '
                      'will not show up.'))
	    self.deferred_functions.append(func)
	    #这里承接上面的add_url_rule,往deferred_functions这个列表里添加了匿名函数,而这个匿名函数就对应着一个视图函数。

    def register(self, app, options, first_registration=False):

        """在Flask.register_blueprint里调用 ,往app里注册"""
        self._got_registered_once = True
        #state是BlueprintSetupState实例,记录了蓝图注册是的各种状态信息
        state = self.make_setup_state(app, options, first_registration)
        #state = make_setup_state实例化了一个BlueprintSetupState
        if self.has_static_folder:
            state.add_url_rule(self.static_url_path + '/<path:filename>',
                               view_func=self.send_static_file,
                               endpoint='static')
        for deferred in self.deferred_functions:
            deferred(state) 
    """这里的deferred_functions就是上个函数record添加的视图函数的列表。
而deferred 就是上面record添加的匿名函数:lambda s: s.add_url_rule(rule, endpoint, view_func, **options),
而"deferred(state) "把state当做实参,等同于state.add_url_rule
state是BlueprintSetupState的实例对象,所以这里上下面都是调用BlueprintSetupState的add_url_rule方法,上文中提到最终实质还是调用app的add_url_rule
所以循环deferred_functions,所有视图函数都会通过BlueprintSetupState的add_url_rule方法也就是app的add_url_rule,添加到app中"""

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值