Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using query string in Python Pyramid route configuration

this is very specific to what I am trying to do so I start describing what it is:

  • a Pyramid app serving plots like http://localhost:6543/path/to/myplot/plot001.png
  • if the plot is not available another image is served (work.png)
  • another part is the deform view which provides a HTML form to enter the configuration for a plot like: http://localhost:6543/path/to/myplot/plot001.png?action=edit. Note here the query string "action=edit".
  • the configuration consists of datafile, templates etc.
  • the form has save (to save the config) and render buttons (http://localhost:6543/path/to/myplot/plot001.png?action=render). Rendering results into a png file which then is used in a static way.

I figured out all the pieces like rendering using Matplotlib etc. but I am new to Pyramid and Deform. I also have a working view that serves the plot from file. The deform form kind of works, too. At the moment it is unclear to me how to best structure the ULRs to distinguish the serve, edit and render usecases. I guess in Pyramid talk this means how to configure the routes for serve_view and 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):
...

I the Pyramid manual I could not find reference how to set parameters in the route. I guess a pointer to some documentation or sample would be sufficient and I can figure out the details myself. Thank you!

like image 227
moin moin Avatar asked Aug 01 '11 10:08

moin moin


2 Answers

I'm not sure you can use contex=Root in that situation, but what you are asking for is probably the 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

Edit:

If your question is more a general question regarding routing, you should create one route per action to keep the code of your view functions shorter and clearer. For example, if you want to edit and render, your routes could look something like this:

__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
like image 22
Antoine Leclair Avatar answered Sep 28 '22 02:09

Antoine Leclair


There are two ways to do this depending on what you prefer for separating your code.

  1. Put all of the logic into your view, separated by 'if' statements on 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
    
  2. Register multiple views and delegate between them using Pyramid's view lookup mechanics.

    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..
    

Hope this helps. It's an excellent example of registering a single url pattern, and using different views for different types of requests on that url.

like image 102
Michael Merickel Avatar answered Sep 28 '22 03:09

Michael Merickel