内容简介:跨flask app使用url_for
用flask的肯定知道url_for,解放了记住url的繁琐。前阵子因为flask臭名昭著的 servername问题彻底拆分了应用程序,在解决了大部分引用和重用后发现应用间导航也是个问题,写硬url显然不科学。这里祭出几大法宝用来解决这个问题:
- 中间件Dispatcher,也可以使用werkzeug.wsgi 的 DispatcherMiddleware,中间件的设计理念真是扩展所必须的呀;
- with nebapp.app_context,没错在每个应用程序中创建邻居app后可以使用它的上下文即可用url_for了;
- 实际使用会有报错,这里需要mock一个request,这里flask准备好了app.test_request_context;
贴一下我在用的Dispatcher
class Dispatcher: """ Allows one to mount middlewares or applications in a WSGI application. This is useful if you want to combine multiple WSGI applications:: app = DispatcherMiddleware(app, { '/app2': app2, '/app3': app3 }) """ def __init__(self, app, mounts=None): self.app = app self.mounts = mounts or {} self.url_for_resolver = URLForResolver( self.mounts ) self.app.dispatcher = self def __call__(self, environ, start_response): script = environ.get('PATH_INFO', '') path_info = '' while '/' in script: if script in self.mounts: app = self.mounts[script] break script, last_item = script.rsplit('/', 1) path_info = '/%s%s' % (last_item, path_info) else: app = self.mounts.get(script, self.app) original_script_name = environ.get('SCRIPT_NAME', '') environ['SCRIPT_NAME'] = original_script_name + script # Convert empty path info values to a forward slash '/' environ['PATH_INFO'] = path_info or '/' return app(environ, start_response) class URLForResolver: """ A URL resolver that provides resolution of `url_for` across multiple apps. """ def __init__(self, mounts): self.mounts=mounts self.apps = list(mounts.values()) self.cache = {} for app in self.apps: app.url_build_error_handlers.append(self) def __call__(self, endpoint, **values): """Attempt to resolve a URL any of the registered apps""" error = Exception('can not find endpoint for %s' % endpoint) parts=endpoint.split('.') path=parts.pop() if len(parts)>1: path='%s.%s'%(parts[1],path) app_name=None if len(parts)>0: app_name=parts[0] # Check if we have a cached look up if endpoint in self.cache: app = self.cache[endpoint] if app: with app.app_context(), app.test_request_context(): ret_path= url_for(path, **values) if ':5000' in ret_path: ret_path=ret_path.replace(':5000','') return ret_path else: raise error if app_name: app = self.mounts[app_name] self.cache[endpoint] = app return self(endpoint, **values) # Attempt to find an app with the registered endpoint for app in self.apps: for rule in app.url_map.iter_rules(): if rule.endpoint == path: # Found - cache the result and call self to return the URL self.cache[endpoint] = app return self(endpoint, **values) # Not found - cache the result and re-raise the error self.cache[endpoint] = None raise error
使用方式:
#初始化 init_apps() apps = create_apps() del apps['/passport'] dispatcher = Dispatcher(passport, mounts=apps) #调用 current_app.dispatcher.url_for_resolver('/appname.blueprint_name.page_name',_external=True))
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- RecyclerView使用指南(一)—— 基本使用
- 如何使用Meteorjs使用URL参数
- 使用 defer 还是不使用 defer?
- 使用 Typescript 加强 Vuex 使用体验
- [译] 何时使用 Rust?何时使用 Go?
- UDP协议的正确使用场合(谨慎使用)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Numerical Methods and Methods of Approximation in Science and En
Karan Surana / CRC Press / 2018-10-31
ABOUT THIS BOOK Numerical Methods and Methods of Approximation in Science and Engineering prepares students and other readers for advanced studies involving applied numerical and computational anal......一起来看看 《Numerical Methods and Methods of Approximation in Science and En》 这本书的介绍吧!