如何确保Pyramid的route_url和route_path生成的URL有效?

时间:2013-10-04 15:05:09

标签: python routes pyramid

在金字塔中使用URL Dispatch并在路由定义中使用模式匹配,我想确保route_path生成的URL有效并与给定路由匹配 - 这是最好的方法吗?

这是我的路线定义 - 我希望/numbers后跟一个等于1或更大的数字字符串...

config.add_route('numbers', 'numbers/{n:[1-9]\d*}/')

然后,当我在视图中生成路线时,这很好:

request.route_url('numbers', n=123)

返回/numbers/123/,这很好......

但是,如果我这样做......

request.route_url('numbers', n='chicken')

金字塔返回/numbers/chicken/,显然与模式不匹配,并在传回应用时会给出404.

有没有办法可以强制金字塔在生成路线时检查n是否匹配给定的模式?这意味着我可以确定route_urlroute_path会提供可在应用中使用的有效网址。

1 个答案:

答案 0 :(得分:4)

您可以使用预生成器在生成网址时添加自定义逻辑。网址中的正则表达式模式仅用于匹配目的。

def check_n(request, elements, kw):
    if not is_valid(kw['n']):
        raise ValueError('invalid url parameter')
    return elements, kw

config.add_route('numbers', 'numbers/{n:[1-9]\d*}/', pregenerator=check_n)

如果你想写一些验证生成的网址的东西,那就不容易了。预生成器不知道正在使用什么路由,路由对象与路径匹配,而不是kwargs。最好的办法是包装路由生成并验证生成的URL,而不是自己验证kwargs。

def validated_route_path(request, *args, **kwargs):
    route_name = args[0]
    path = request.route_path(*args, **kwargs)
    route_intr = request.registry.introspector.get('routes', route_name)
    route = route_intr['object']
    if route.match(path) is None:
        raise ValueError('invalid url generated')
    return path

config.add_request_method(validated_route_path)

request.validated_route_path('numbers', n='chicken') # -> ValueError