2011-08-01 143 views
6

这是非常具体的什么,我试图这样做,我开始描述它是什么:使用查询字符串

  • 金字塔应用中投放情节像http://localhost:6543/path/to/myplot/plot001.png
  • 如果情节不可用另一个图像被提供(work.png)
  • 另一部分是变形视图,它提供了一个HTML表单来输入配置,例如:http://localhost:6543/path/to/myplot/plot001.png?action=edit。请注意查询字符串“action = edit”。
  • 配置由数据文件,模板等组成
  • 窗体具有save(保存配置)和渲染按钮(http:// localhost:6543/path/to/myplot/plot001.png?action = render )。将结果呈现为一个png文件,然后以静态方式使用。

我想出了所有使用Matplotlib等渲染的东西,但我是Pyramid和Deform的新手。我也有一个工作视图,用于从文件中提供图表。变形也是一种作品。目前我还不清楚如何最好地构建ULR来区分服务,编辑和呈现用例。我猜在金字塔这里说这意味着如何配置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): 
... 

我金字塔手册我找不到参考如何在路线中设置参数。我想一个指向一些文档或样本的指针就足够了,我可以自己弄清楚细节。谢谢!

+0

金字塔有他们称之为Multidict的机制。我认为这是访问查询字符串的方式。我将合并两个视图的情节和编辑成一个,并使用如下所示的区别: if request.GET.getall('action')中的'编辑': #编辑配置 – mark

+0

你在说什么上面的评论是好的,这可能是我会这样做的方式;您可以将自定义谓词交替添加到add_route语句中,以便匹配查询字符串中的两个路由。请参阅http://docs.pylonsproject.org/projects/pyramid/1.1/narr/urldispatch.html#custom-route-predicates –

回答

11

有两种方式这取决于你想要分离你的代码。

  1. 将所有的逻辑放入您的视图中,由request.GET.get('action')上的'if'语句分隔。它们之间

    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 
    
  2. 注册多个视图和委托使用金字塔的看法查找机制。

    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上的不同类型的请求使用不同的视图。

+0

request_param ='action = edit'它是!我对此感到兴奋。金字塔太棒了! – mark

1

我不确定你可以在那种情况下使用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

编辑:

如果您的问题是关于多路由一个一般性的问题,你应该创建o ne行动,以保持您的视图功能的代码更短,更清晰。例如,如果要编辑和渲染,你的路由可能是这个样子:

__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 
+1

我不认为matchdict是URL参数的选择。参数没有定义的顺序。我的意思是如果你有多个参数你可以互换它们。就我理解的匹配而言,它意味着覆盖“?”左侧的URL部分。 – mark

0

更有效的方法是在url中指定动作。而且,您甚至可以在相同的路线名称或多个路线上提供不同的操作。

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