如何将 Pylons 中的 /{controller}/{action}/{id} 路由移植到 Pyramid

How to port /{controller}/{action}/{id} routes in Pylons to Pyramid

所以我正在移植一些旧的 Py2/Pylons 应用程序,它的路由定义在 https://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/pylons/examples.html 第 #3 部分中,这在 Pyramid 中是不可能的 - 那么如何处理?

我对 Pylons 和 Pyramid 都不熟悉,所以如果它很明显,我仍然想要提示。

我有 8 个控制器,每个控制器有 ~2-5 个动作,其中只有一些使用 {id},我想我需要用单独的 route_names 装饰每个控制器中的每个动作函数,除了对于那些不使用任何 id 的:

@view_defaults(renderer='go.pt', route_name='go')
class GoView:
    def __init__(self, request):
        self.request = request

    @view_config(match_param="action=list")
    def list(self):
        return {'name': 'Go list'}

    @view_config(route_name='go_edit')
    def edit(self):
        return {'name': 'Go edit id: {}'.format(self.request.matchdict["id"])}

    config.add_route("go", "/go/{action}"). # deals with all non-id routes pr controller
    config.add_route("go_edit", "/go/edit/{id}") # one for each controller+action using id

但是,与 Pylons 代码相比,我需要添加的路由相当多 - 这是金字塔风格,还是有更好的方法?实际上,无论是否使用 ID,为每个操作添加特定路由是否更好,即使它会生成更多对 config.add_route?

的调用

Pyramid 本身需要精细的路由定义。您可以为此编写助手

def add_action_routes(config, name, path=None):
    if path is None:
        path = name
    if not path.endswith('/'):
        path += '/'
    config.add_route(name, path)
    config.add_route(name + '_action', path + '{action}')
    config.add_route(name + '_id', path + '{action}/{id}')

add_action_routes(config, 'go')

然后您可以根据需要使用 view_defaultsview_config 将视图连接到这些路线。另一方面,您可以制作自己的 url 生成器,它可以正确处理生成正确格式的 url。

def make_action_url(request, name, action=None, id=None, **kw):
    if action is None:
        return request.route_url(name, **kw)
    if id is None:
        return request.route_url(name + '_action', action=action, **kw)
    return request.route_url(name + '_id', action=action, id=id, **kw)

config.add_request_method(make_action_url, 'action_url')

这将允许您的代码使用 request.action_url(...) 生成 urls 而无需过多地使用路由名称。