代码艺术家
Code artist

很喜欢释迦牟尼佛的一句话:“无论你遇见谁,他都是你生命该出现的人,绝非偶然,他一定教会你一些什么”。

有问题 问我 问Google

flask之blueprint和url_for的关系

主旨:

主要记录在使用flask buleprint的时候遇到的一些问题。

问题1:

在创建蓝图的时候比如我在A/keystone.py创建一个蓝图
a_keystone = Blueprint('keystone',__name__),没毛病。
当我在B/keystone.py创建一个蓝图的时候b_keystone = Blueprint('keystone',__name__)。也没毛病哈,但是当我启动服务的时候就会报错,说是注册蓝图冲突。报错如下:

(blueprint, self.blueprints[blueprint.name], blueprint.name)
AssertionError: A blueprint's name collision occurred between <flask.blueprints.Blueprint object at 0x10e090bd0> and <flask.blueprints.Blueprint object at 0x10e090450>.  Both share the same name "keystone".  Blueprints that are created on the fly need unique names.

我们先看一下flask相关的源码:

    # blueprints.py
class Blueprint(_PackageBoundObject):
    # indicator.
    warn_on_modifications = False
    _got_registered_once = False

    def __init__(self, name, import_name, static_folder=None,
                 static_url_path=None, template_folder=None,
                 url_prefix=None, subdomain=None, url_defaults=None,
                 root_path=None):
        _PackageBoundObject.__init__(self, import_name, template_folder,
                                     root_path=root_path)
        self.name = name
        self.url_prefix = url_prefix
        self.subdomain = subdomain
        self.static_folder = static_folder
        self.static_url_path = static_url_path
        self.deferred_functions = []
        if url_defaults is None:
            url_defaults = {}
        self.url_values_defaults = url_defaults

继承_PackageBoundObject的Blueprint类的在初始化函数中,初始化了很多参数:name, url_prefix, subdomain, static_folder...,这些参数具体是什么意思呢,我们还是以例子为基准,没有涉及到的参数(即设置为None)暂时不管. 在官方文档给出的My First Buleprint例子中:

    simple_page = Blueprint('simple_page', __name__,
                        template_folder='templates')

传入的参数有: self.name = 'simple_page', import_name = name, template_folder = 'templates'. 在我们的例子中name即是 'blueprintDemo'(ps:python中__name__默认为所在文件名)

注意:中间省略一些内容,详情参考http://www.jianshu.com/p/a55b9319a3e0
当我们注册蓝图

    app.register_blueprint(simple_page, url_prefix='/page')

重点来啦!

        @setupmethod
    def register_blueprint(self, blueprint, **options):
        # indicator.
        first_registration = False
        if blueprint.name in self.blueprints:
            assert self.blueprints[blueprint.name] is blueprint, \
                'A blueprint\'s name collision occurred between %r and ' \
                '%r.  Both share the same name "%s".  Blueprints that ' \
                'are created on the fly need unique names.' % \
                (blueprint, self.blueprints[blueprint.name], blueprint.name)
        else:
            # 添加蓝到self.blueprints.
            self.blueprints[blueprint.name] = blueprint
            self._blueprint_order.append(blueprint)
           # 设置为True.
            first_registration = True
        blueprint.register(self, options, first_registration)

这个时候我们有一个疑问在通过url_for('蓝图名.函数名')进行页面跳转的时候(注意,不全是页面跳转,取决于函数里的逻辑,我这里通过页面跳转验证。)这个蓝图名怎么理解?比如xxx = Blueprint('###',__name__,url_prefix='/a',template_folder='./template-test')是xxx还是###(xxx和###表示可以起合法的任意变量,由于不确定暂用特殊来代替)
验证项目请见github:https://github.com/jasonhubs/flask_test

通过验证得知:Blueprint()里面的参数有个为蓝图名,这个很重要,而且在所有蓝图当中必须要唯一标志,因为在template中通过url_for('蓝图名.函数名')跳转页面的时候很重要,至于xxx = Blueprint(...)xxx主要作用就是为了注册的时候用

意外发现

在flask template中注释的部分依然不起作用,如下:
<!--<a href="url_for('bp.user')">this will redirect to user.html!</a>-->,在这行代码中如果url_for里面的错误,依然还是会报错的,我很纳闷,为啥注释了,还起作用。我用的IDE为pycharm。这个暂时没解决。解决了我会及时更新文档。有知道的朋友也告诉我一下,谢谢。

posted @ 2017-04-06 17:47  Jason‘  阅读(1377)  评论(0编辑  收藏  举报