2012-01-11 2 views
1

В старой школе webapp, маршрутизация на основе app.yaml позволяла вам проверять регулярные выражения и, если они совпадали, обрабатывать запрос обработчиком, чье имя основано на найденном шаблоне. Например, \ 1_handler.py отправит пользователю user_handler.py, если совпадающий шаблон был «пользователем».Advanced Webapp2 Routing

Есть ли способ сделать то же самое с webapp2.Route? Может ли ленивый обработчик или параметры method_handler быть основан на совпадающих шаблонах в шаблоне?

+1

Здесь вы говорите о двух разных вещах - app.yaml и вашей веб-среде. Вы все еще можете использовать маршрутизацию на основе app.yaml с помощью webapp2. –

+0

Да, я знаю. Но я хочу, чтобы запрос обрабатывался другим методом в классе обработчика запроса на основе содержимого URL-адреса. Так что если это пользователь/шоу, я хочу, чтобы он перешел к Handler: show, и если он пользователь/добавить, я хочу, чтобы он перешел к User: add. И я делаю это для трех типов объектов (пользователь + 2) и 5 ​​типов действий. Вы можете сделать это на 15 маршрутах ineebapp2. Но я вижу, как я могу сузить его до 3 или 1. Я не вижу, как определение app.yaml позволит мне определить мето. –

+0

Это не будет, но это не то, что вы задавали в исходном вопросе. На самом деле я не уверен, как это относится. –

ответ

4

webapp2 не позволяет маршрутизировать это. Я считаю, что наиболее разумным решением является создание настраиваемого диспетчера для webapp2.Router.

Можно установить пользовательский диспетчеру так:

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

Вот это не тестировался эскизом для диспетчера, код основан на 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 

Этот код должен позволять для регистрации таких правил:

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

Этот пример не позволяет использовать переменные из шаблона в имени метода, например: module.Class:action_{method}. В классе Route эта конечная точка разделяется точкой с запятой, а значения хранятся в route.method_name и route.handler.

Смежные вопросы