superset的url是通过@expose装饰器将url添加到视图的_urls属性中,然后在appbuilder.add_view中注册蓝图的时候,将url注册到对应的蓝图上。
用expose装饰函数
def expose(url='/', methods=('GET',)):
def wrap(f):
if not hasattr(f, '_urls'):
f._urls = []
f._urls.append((url, methods)) # 将url和methods添加到函数的_urls属性中
return f
return wrap
为每一个继承来BaseView的视图注册蓝图
def add_view(self, baseview, name, href="", icon="",
label="", category="",
category_icon="", category_label=""):
baseview = self._check_and_init(baseview)
log.info(LOGMSG_INF_FAB_ADD_VIEW.format(baseview.__class__.__name__, name))
if not self._view_exists(baseview):
baseview.appbuilder = self
self.baseviews.append(baseview)
self._process_inner_views()
if self.app:
self.register_blueprint(baseview) #为视图注册蓝图
self._add_permission(baseview)
self.add_link(name=name, href=href, icon=icon, label=label,
category=category, category_icon=category_icon,
category_label=category_label, baseview=baseview)
return baseview
将urls添加到蓝图上
首先看一下appbuilder的register_blueprint()函数
def register_blueprint(self, baseview, endpoint=None, static_folder=None):
self.get_app.register_blueprint(baseview.create_blueprint(self, endpoint=endpoint, static_folder=static_folder)) # 第一个参数是blueprint的实例
下面来看一下BaseView的create_blueprint()函数
def create_blueprint(self, appbuilder,
endpoint=None,
static_folder=None):
# Store appbuilder instance
self.appbuilder = appbuilder
# If endpoint name is not provided, get it from the class name
self.endpoint = endpoint or self.__class__.__name__
if self.route_base is None:
self.route_base = '/' + self.__class__.__name__.lower()
self.static_folder = static_folder
if not static_folder:
# Create blueprint and register rules
self.blueprint = Blueprint(self.endpoint, __name__,
url_prefix=self.route_base,
template_folder=self.template_folder)
else:
self.blueprint = Blueprint(self.endpoint, __name__,
url_prefix=self.route_base,
template_folder=self.template_folder,
static_folder=static_folder) # 生成blueprint
self._register_urls() # 将urls添加到蓝图上
return self.blueprint
_register_urls()函数将url添加到蓝图上
def _register_urls(self):
for attr_name in dir(self):
attr = getattr(self, attr_name)
if hasattr(attr, '_urls'):
for url, methods in attr._urls:
self.blueprint.add_url_rule(url,
attr_name,
attr,
methods=methods) # 添加url
至此,superset的url生成原理就讲完了