金字塔路由匹配和查询参数

5 投票
2 回答
10909 浏览
提问于 2025-04-17 14:57

我有一个用Pyramid框架做的网络服务,下面是一些代码示例:

视图声明:

@view_config(route_name="services/Prices/GetByTicker/")
def GET(request):
    ticker = request.GET('ticker')
    startDate = request.GET('startDate')
    endDate = request.GET('endDate')
    period = request.GET('period')

路由设置:

config.add_route('services/Prices/GetByTicker/', 'services/Prices/GetByTicker/{ticker}/{startDate}/{endDate}/{period}')

我知道这些代码有问题,但我不太清楚Pyramid的规范是什么。目前这个代码能正常工作,也就是说请求能成功转到视图,但接下来我遇到了一个“字典对象不可调用”的错误。

这个网址看起来很糟糕:

@root/services/Prices/GetByTicker/ticker=APPL/startDate=19981212/endDate=20121231/period=d

理想情况下,我希望能用一个更好的网址,比如:

@root/services/Prices/GetByTicker/?ticker=APPL&startDate=19981212&endDate=20121231&period=d

有没有Pyramid方面的高手愿意花五分钟时间来解释一下我哪里做错了?

2 个回答

5

查询字符串会变成一个叫做 request.GET 的字典。你现在用的是括号来调用这个字典,而不是用方括号来访问里面的内容。比如说,有这样一个网址:

@root/services/Prices/GetByTicker/?ticker=APPL&startDate=19981212&endDate=20121231&period=d

request.GET['ticker'] # -> 'APPL' or an exception if not available
request.GET.get('ticker') # -> 'APPL' or None if not available
request.GET.get('ticker', 'foo') # -> 'APPL' or 'foo' if not available
request.GET.getall('ticker') # -> ['APPL'] or [] if not available

最后一个选项很有用,如果你预期 ticker 会被多次提供的话。

request.paramsrequest.GETrequest.POST 的结合,其中 request.POST 是一个字典,代表请求体中的表单数据。

总之,答案是 request.GET('ticker') 这种写法并不是我提到的选项之一,所以别再这样做了。:-)

14

从你的示例代码来看,我觉得你在使用URL调度

所以应该像这样:

config.add_route('services/Prices/GetByTicker/', 'services/Prices/GetByTicker/')

那么像这样的URL:
@root/services/Prices/GetByTicker/?ticker=APPL&startDate=19981212&endDate=20121231&period=d
就可以匹配到它。

--编辑--
你不一定要把路由名称写成"services/Prices/GetByTicker",而且你可以通过request.params['key']来获取GET参数。
视图声明:

@view_config(route_name="services_Prices_GetByTicker")
def services_Prices_GetByTicker(request):
    ticker = request.params['ticker']
    startDate = request.params['startDate']
    endDate = request.params['endDate']
    period = request.params['period']

路由:

config.add_route('services_Prices_GetByTicker', 'services/Prices/GetByTicker/')

撰写回答