Pregunta

En la webapp de la vieja escuela, el enrutamiento basado en App.yaml le permitió verificar las expresiones regulares y, si se combina, procesar una solicitud por un controlador cuyo nombre se basa en el patrón encontrado. Por ejemplo, 1_handler.py se enviaría a user_handler.py si el patrón coincidente fuera 'Usuario'.

¿Hay alguna forma de hacer lo mismo con WebApp2.Route? ¿Puede el controlador perezoso o los parámetros Method_handler basarse en los patrones coincidentes en la plantilla?

¿Fue útil?

Solución

WebApp2 no permite enrutar así. Creo que la solución más razonable es escribir un despachador personalizado para webapp2.Router.

Es posible establecer un despachador personalizado como este:

app = WSGIApplication(...)
app.router.set_dispatcher(custom_dispatcher)

Aquí hay un boceto no probado Para el despachador, el código se basa en 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

Este código debe permitir registrar reglas como esta:

 app = WSGIApplication([
     (r'module/<module>/<action>/<argument>', 'modules.{module}.action_{action}'),
 ])

Este ejemplo no permite usar variables del patrón en el nombre del método, por ejemplo: module.Class:action_{method}. En Route clase Este punto final está dividido por semicolon y valores almacenados en route.method_name y route.handler.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top