我完成了我的研究并进行了一些模式匹配试验,但我仍然无法弄清楚如何:
使路线的一部分可选。 e.g:
/ required (/ optional / {str}) 括号中的部分是可选的。
将限制应用于路由,因此它必须匹配元组中的项目而不是通配符字符串。
/ view_1 / {('opt_a','opt_b','opt_c'...)} 在这种情况下,如果元组中的项目匹配,则路由(如果不是404或FORBIDDEN
我如何实现这些目标?
谢谢。
答案 0 :(得分:12)
Pyramid不支持路线中的可选模式。另一个答案表明*optional
,但这比你要求的一个可选占位符要多得多,并且在路径的末尾没有任何选项可以获得更多模式。
config.add_route('name_with_optional', '/required/{optional}/{str}')
config.add_route('name', '/required/{str}')
现在你想要为我想象的同时使用相同的视图,因为你认为占位符是可选的。因此,只需为两种情况注册视图:
@view_config(route_name='name_with_optional')
@view_config(route_name='name')
def my_view(request):
optional = request.matchdict.get('optional')
如果optional
是匹配的路由模式,则None
变量将为'name'
。
至于你的第二个问题,你可以简单地创建一个自定义谓词。这可以在路线或视图上(请记住它们在金字塔中是分开的)。谓词的签名在每种情况下都不同。
路线上的谓词(不太常见):
def opt_must_contain(info, request):
opt = info['match'].get('opt')
return opt in ('opt_a', 'opt_b', 'opt_c')
config.add_route('my_route', '/view_1/{opt}', custom_predicates=[opt_must_contain])
如果此谓词返回False
,则可以匹配具有相同模式的另一个路由(忽略该路由)。
视图的谓词(更常见):
def opt_must_contain(context, request):
opt = request.matchdict.get('opt')
return opt in ('opt_a', 'opt_b', 'opt_c')
config.add_route('my_route', '/view_1/{opt}')
@view_config(route_name='my_route', custom_predicates=[opt_must_contain])
def my_view(request):
opt = request.matchdict.get('opt')
在视图中,我们知道opt
是必需的选项之一。
答案 1 :(得分:3)
解释起来很棘手,但你想要的是http://docs.pylonsproject.org/projects/pyramid/en/1.0-branch/narr/hybrid.html - 这不是最简单的阅读,而是解释你所追求的目标。
进一步研究后更新
使用:
config.add_route('name', 'foo/*optional')
可以将剩余的路径元素作为元组接收
自定义谓词可用于过滤网址调度,如http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html?awesome
中所述答案 2 :(得分:0)
除了使用自定义路由谓词之外,您还可以使用URL遍历来实现这两点。我写了detailed answer来回答你的另一个问题。
我认为遍历对于此类用例来说是一种更清晰,更“自然”的解决方案。