Avanzate Webapp2 Routing
-
27-10-2019 - |
Domanda
Nella vecchia webapp scuola, app.yaml Based Routing vi ha permesso di verificare la presenza di espressioni regolari e se abbinato, elabora una richiesta di un gestore il cui nome è basato sul modello trovato. Per esempio \ 1_handler.py sarebbe spedizione verso user_handler.py se il modello abbinato è stato 'utente'.
C'è un modo per fare la stessa cosa con webapp2.Route? Può il gestore pigri oi parametri method_handler essere basati sui modelli abbinati a modello?
Soluzione
webapp2 non permette di instradare in quel modo. Penso che la soluzione più ragionevole è quello di scrivere un dispatcher personalizzato per webapp2.Router
.
E 'possibile impostare un dispatcher personalizzato come questo:
app = WSGIApplication(...)
app.router.set_dispatcher(custom_dispatcher)
Ecco un non testato schizzo per il dispatcher, il codice si basa su webapp2.Router.default_dispatcher
:
from webapp2 import import_string
def custom_dispatcher(router, request, response):
route, args, kwargs = rv = router.match(request)
request.route, request.route_args, request.route_kwargs = rv
handler = route.handler
if isinstance(handler, basestring):
handler, args, kwargs = _parse_handler_template(handler, args, kwargs)
if handler not in self.handlers:
router.handlers[handler] = handler = import_string(handler)
else:
handler = router.handlers[handler]
return router.adapt(handler)(request, response)
def _parse_handler_template(handler, args, kwargs):
"""replace {key} in `handler` with values from `args` or `kwargs`.
Replaced values are removed from args/kwargs."""
args = list(args)
kwargs = dict(kwargs)
def sub(match):
if kwargs:
return kwargs.pop(match.group().strip('{}'))
else:
return args.pop(int(match.group().strip('{}'))
return re.sub('{.*?}', sub, handler), args, kwargs
Questo codice dovrebbe consentire di registrare un regole in questo modo:
app = WSGIApplication([
(r'module/<module>/<action>/<argument>', 'modules.{module}.action_{action}'),
])
In questo esempio non permette di utilizzare le variabili da modello in nome del metodo, ad esempio: module.Class:action_{method}
. In classe Route
questo endpoint è diviso dal punto e virgola e valori memorizzati in route.method_name
e route.handler
.