forked from orbit-oss/flask
Register most stuff only once
This commit is contained in:
parent
7a08331ac0
commit
f7e71b518f
2 changed files with 26 additions and 17 deletions
|
|
@ -583,6 +583,7 @@ class Flask(_PackageBoundObject):
|
|||
|
||||
.. versionadded:: 0.7
|
||||
"""
|
||||
first_registration = False
|
||||
if blueprint.name in self.blueprints:
|
||||
assert self.blueprints[blueprint.name] is blueprint, \
|
||||
'A blueprint\'s name collision ocurred between %r and ' \
|
||||
|
|
@ -590,7 +591,8 @@ class Flask(_PackageBoundObject):
|
|||
(blueprint, self.blueprints[blueprint.name], blueprint.name)
|
||||
else:
|
||||
self.blueprints[blueprint.name] = blueprint
|
||||
blueprint.register(self, options)
|
||||
first_registration = True
|
||||
blueprint.register(self, options, first_registration)
|
||||
|
||||
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
|
||||
"""Connects a URL rule. Works exactly like the :meth:`route`
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import os
|
||||
from functools import update_wrapper
|
||||
|
||||
from .helpers import _PackageBoundObject, _endpoint_from_view_func
|
||||
|
||||
|
|
@ -19,10 +20,11 @@ class BlueprintSetupState(object):
|
|||
application.
|
||||
"""
|
||||
|
||||
def __init__(self, blueprint, app, options):
|
||||
def __init__(self, blueprint, app, options, first_registration):
|
||||
self.app = app
|
||||
self.blueprint = blueprint
|
||||
self.options = options
|
||||
self.first_registration = first_registration
|
||||
|
||||
subdomain = self.options.get('subdomain')
|
||||
if subdomain is None:
|
||||
|
|
@ -64,17 +66,23 @@ class Blueprint(_PackageBoundObject):
|
|||
def _record(self, func):
|
||||
self.deferred_functions.append(func)
|
||||
|
||||
def make_setup_state(self, app, options):
|
||||
return BlueprintSetupState(self, app, options)
|
||||
def _record_once(self, func):
|
||||
def wrapper(state):
|
||||
if state.first_registration:
|
||||
func(state)
|
||||
return self._record(update_wrapper(wrapper, func))
|
||||
|
||||
def register(self, app, options):
|
||||
def make_setup_state(self, app, options, first_registration=False):
|
||||
return BlueprintSetupState(self, app, options, first_registration)
|
||||
|
||||
def register(self, app, options, first_registration=False):
|
||||
"""Called by :meth:`Flask.register_blueprint` to register a blueprint
|
||||
on the application. This can be overridden to customize the register
|
||||
behavior. Keyword arguments from
|
||||
:func:`~flask.Flask.register_blueprint` are directly forwarded to this
|
||||
method in the `options` dictionary.
|
||||
"""
|
||||
state = self.make_setup_state(app, options)
|
||||
state = self.make_setup_state(app, options, first_registration)
|
||||
if self.has_static_folder:
|
||||
state.add_url_rule(self.static_url_path + '/<path:filename>',
|
||||
view_func=self.send_static_file,
|
||||
|
|
@ -96,9 +104,8 @@ class Blueprint(_PackageBoundObject):
|
|||
"""Like :meth:`Flask.add_url_rule` but for a module. The endpoint for
|
||||
the :func:`url_for` function is prefixed with the name of the module.
|
||||
"""
|
||||
def register_rule(state):
|
||||
state.add_url_rule(rule, endpoint, view_func, **options)
|
||||
self._record(register_rule)
|
||||
self._record(lambda s:
|
||||
s.add_url_rule(rule, endpoint, view_func, **options))
|
||||
|
||||
def endpoint(self, endpoint):
|
||||
"""Like :meth:`Flask.endpoint` but for a module. This does not
|
||||
|
|
@ -108,7 +115,7 @@ class Blueprint(_PackageBoundObject):
|
|||
def decorator(f):
|
||||
def register_endpoint(state):
|
||||
state.app.view_functions[endpoint] = f
|
||||
self._record(register_endpoint)
|
||||
self._record_once(register_endpoint)
|
||||
return f
|
||||
return decorator
|
||||
|
||||
|
|
@ -117,7 +124,7 @@ class Blueprint(_PackageBoundObject):
|
|||
is only executed before each request that is handled by a function of
|
||||
that module.
|
||||
"""
|
||||
self._record(lambda s: s.app.before_request_funcs
|
||||
self._record_once(lambda s: s.app.before_request_funcs
|
||||
.setdefault(self.name, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -125,7 +132,7 @@ class Blueprint(_PackageBoundObject):
|
|||
"""Like :meth:`Flask.before_request`. Such a function is executed
|
||||
before each request, even if outside of a module.
|
||||
"""
|
||||
self._record(lambda s: s.app.before_request_funcs
|
||||
self._record_once(lambda s: s.app.before_request_funcs
|
||||
.setdefault(None, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -134,7 +141,7 @@ class Blueprint(_PackageBoundObject):
|
|||
is only executed after each request that is handled by a function of
|
||||
that module.
|
||||
"""
|
||||
self._record(lambda s: s.app.after_request_funcs
|
||||
self._record_once(lambda s: s.app.after_request_funcs
|
||||
.setdefault(self.name, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -142,7 +149,7 @@ class Blueprint(_PackageBoundObject):
|
|||
"""Like :meth:`Flask.after_request` but for a module. Such a function
|
||||
is executed after each request, even if outside of the module.
|
||||
"""
|
||||
self._record(lambda s: s.app.after_request_funcs
|
||||
self._record_once(lambda s: s.app.after_request_funcs
|
||||
.setdefault(None, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -150,7 +157,7 @@ class Blueprint(_PackageBoundObject):
|
|||
"""Like :meth:`Flask.context_processor` but for a module. This
|
||||
function is only executed for requests handled by a module.
|
||||
"""
|
||||
self._record(lambda s: s.app.template_context_processors
|
||||
self._record_once(lambda s: s.app.template_context_processors
|
||||
.setdefault(self.name, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -158,7 +165,7 @@ class Blueprint(_PackageBoundObject):
|
|||
"""Like :meth:`Flask.context_processor` but for a module. Such a
|
||||
function is executed each request, even if outside of the module.
|
||||
"""
|
||||
self._record(lambda s: s.app.template_context_processors
|
||||
self._record_once(lambda s: s.app.template_context_processors
|
||||
.setdefault(None, []).append(f))
|
||||
return f
|
||||
|
||||
|
|
@ -167,6 +174,6 @@ class Blueprint(_PackageBoundObject):
|
|||
handler is used for all requests, even if outside of the module.
|
||||
"""
|
||||
def decorator(f):
|
||||
self._record(lambda s: s.app.errorhandler(code)(f))
|
||||
self._record_once(lambda s: s.app.errorhandler(code)(f))
|
||||
return f
|
||||
return decorator
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue