在Python Pyramid路由配置中使用查询字符串
这段内容是关于我正在做的一个具体项目,所以我来描述一下它的情况:
- 这是一个Pyramid应用程序,用来展示图表,比如这个链接:http://localhost:6543/path/to/myplot/plot001.png
- 如果这个图表不可用,就会显示另一张图片(work.png)
- 还有一个部分是deform视图,它提供了一个HTML表单,可以输入图表的配置,比如:http://localhost:6543/path/to/myplot/plot001.png?action=edit。这里需要注意的是查询字符串“action=edit”。
- 这个配置包括数据文件、模板等等。
- 表单有保存按钮(用来保存配置)和渲染按钮(http://localhost:6543/path/to/myplot/plot001.png?action=render)。渲染的结果会生成一个png文件,然后以静态方式使用。
我已经搞清楚了很多细节,比如如何使用Matplotlib进行渲染等等,但我对Pyramid和Deform还不太熟悉。我也有一个可以从文件中展示图表的视图。deform表单也能基本工作。目前我不太清楚如何最好地结构化URL,以区分展示、编辑和渲染这几种用法。我想在Pyramid中,这意味着如何配置serve_view和edit_view的路由。
__init__.py:
config.add_route('serve_route',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png')
config.add_route('edit_route',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png')
# can I use query strings like "?action=edit" here to distinguish the difference?
views.py:
@view_config(context=Root, route_name='serve_route')
def plot_view(context, request):
...
@view_config(context=Root, renderer='bunseki:templates/form.pt', route_name='edit_route')
def edit_view(request):
...
在Pyramid手册中,我找不到关于如何在路由中设置参数的说明。我想如果能指向一些文档或示例就足够了,我可以自己搞定细节。谢谢!
3 个回答
一种更有效的方法是直接在网址里指定你想要的操作。你甚至可以在同一个路由名称上提供不同的操作,或者多个操作。
config.add_route('serve_route', '/{project_name}/testruns/{testrun_name}/plots/{action}/{plot_name}.png')
views.py
@view_config(context=Root, route_name='serve_route', action='view')
def plot_view(request):
pass
或者使用查询字符串
`config.add_route('serve_route',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png')
views.py
@view_config(context=Root, route_name='serve_route')
def plot_view(request):
try:
action = getattr(self._request.GET, 'action')
except AttributeError:
raise
我不太确定在这种情况下是否可以使用 contex=Root
,但你问的内容可能是 matchdict
。
__init__.py:
config.add_route('serve_route',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png')
views.py:
@view_config(route_name='serve_route')
def plot_view(request):
project_name = request.matchdict['project_name']
action = request.params.get('action', None)
http://docs.pylonsproject.org/projects/pyramid/1.1/narr/urldispatch.html#matchdict
补充:
如果你的问题更像是关于路由的一般性问题,你应该为每个操作创建一个路由,这样可以让你的视图函数代码更简洁明了。例如,如果你想进行编辑和渲染,你的路由可以像这样:
__init__.py:
config.add_route('render_plot',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png')
config.add_route('edit_plot',
'/{project_name}/testruns/{testrun_name}/plots/{plot_name}/edit')
views.py:
@view_config('render_plot')
def render(request):
pass
@view_config('edit_plot', renderer='bunseki:templates/form.pt')
def edit(request):
pass
根据你喜欢的代码分隔方式,有两种方法可以做到这一点。
把所有的逻辑放在你的视图里,用 'if' 语句来区分
request.GET.get('action')
的不同情况。config.add_route('plot', '/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png') config.scan() @view_config(route_name='plot') def plot_view(request): action = request.GET('action') if action == 'edit': # do something return render_to_response('bunseki:templates/form.pt', {}, request) # return the png
注册多个视图,然后通过 Pyramid 的视图查找机制在它们之间进行切换。
config.add_route('plot', '/{project_name}/testruns/{testrun_name}/plots/{plot_name}.png') config.scan() @view_config(route_name='plot') def plot_image_view(request): # return the plot image @view_config(route_name='plot', request_param='action=edit', renderer='bunseki:templates/form.pt') def edit_plot_view(request): # edit the plot return {} # etc..
希望这对你有帮助。这是一个很好的例子,展示了如何注册一个单一的 URL 模式,并对该 URL 的不同请求使用不同的视图。