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

jam*_*esc 1 python routes pyramid

在 Pyramid 中使用 URL Dispatch 并在路由定义中使用模式匹配,我想确保生成的 URLroute_path是有效的并匹配给定的路由 - 最好的方法是什么?

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

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

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

request.route_url('numbers', n=123)
Run Code Online (Sandbox Code Playgroud)

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

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

request.route_url('numbers', n='chicken')
Run Code Online (Sandbox Code Playgroud)

Pyramid 返回/numbers/chicken/显然与模式不匹配并且在传递回应用程序时会给出 404。

有没有办法可以强制 Pyramid 在n生成路线时检查是否与给定模式匹配?这意味着我可以确定route_url并且route_path会提供可以在应用程序中使用的有效 URL。

Mic*_*kel 6

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

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)
Run Code Online (Sandbox Code Playgroud)

如果你想写一些东西来验证生成的 url,这并不容易。预生成器不知道正在使用什么路由并且路由对象匹配路径,而不是 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
Run Code Online (Sandbox Code Playgroud)