Chaining of views using wrapper

56 views
Skip to first unread message

Jay T

unread,
Sep 12, 2011, 1:53:33 AM9/12/11
to pylons-...@googlegroups.com
Can someone please provide a simple example of view chaining using wrapper argument in View Config ?
I am using pyramid_handlers for route/view declaration.

I think I am missing something simple but shouldn't this work:

@view_config(name='wrapped',wrapper='wrapper',renderer='string')
def wrapped(request):
   return Response('Response from wrapped view')


@view_config(name='wrapper',renderer='string')
def wrapper(request):
    wrappedresp  = request.wrapped_response
    return Response('Response from wrapped view is %s'%wrappedresp)
   

I can't seem to access request.wrapped_response and it gives an error "'Request' object has no attribute 'wrapped_response'"


Thanks,
Jay

  
 

Michael Merickel

unread,
Sep 12, 2011, 3:27:39 AM9/12/11
to pylons-...@googlegroups.com
1) What url are you visiting when you get the error?
2) There are no routes in play here, so I can't tell if your talk of using pyramid_handlers is a red herring, or the actual problem. Can you elaborate? And to clarify why I care, render_view_to_response (the underlying code behind wrapping views) only works with traversal.

--

Michael

Jay T

unread,
Sep 12, 2011, 1:45:01 PM9/12/11
to pylons-...@googlegroups.com
Here is the handler setup.

config.add_handler('wrapper','/test_wrapper/{action}',handler=TestWrapper)
config.add_handler('wrapped','/test_wrapper/{action}',handler=TestWrapper)

Here is the handler code:

class TestWrapper(BaseView):
   
    @action(name='wrapper',renderer='string',permission='__no_permission_required__')
    def wrapper(self):
        #Use who_api to perform LDAP login.
        resp = self.request.wrapped_response
        return Response('From wrapped = %s'%resp)
       
    @action(name='wrapped',renderer='string',permission='__no_permission_required__',wrapper='wrapper')
    def wrapped(self):
        return Response('From wrapped')

class BaseView(object):
    __autoexpose__= None
    def __init__(self,request):
        self.request = request
     

Browsing to : http://<server:port>/test_wrapper/wrapped results in ValueError: No wrapper view named 'wrapper' found when executing view named ''
Browsing to http://<server:port>/test_wrapper/wrapper
AttributeError: 'Request' object has no attribute 'wrapped_response'


I don't know if I am down the right path ehre but what I am really interested in is the capability to call a view from within another view. I am looking for capability to have a generic view which invokes views based on query string parameter and returns response from the inner view back. Just to add the generic view would be called as an Ajax request.

Thanks,
Jay
--
You received this message because you are subscribed to the Google Groups "pylons-discuss" group.
To post to this group, send email to pylons-...@googlegroups.com.
To unsubscribe from this group, send email to pylons-discus...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.

Michael Merickel

unread,
Sep 12, 2011, 11:01:32 PM9/12/11
to pylons-...@googlegroups.com
As I said in my previous reply, the wrapped views do not work with routes, only with traversal. Thus they will not work with handlers, which are an abstraction on top of routes.

Pyramid does not have a public api for invoking other views during a request. Instead it provides a very extensible mechanism for looking up views based on properties of the request itself, as well as supporting decorators. A very common paradigm is to just abstract common functionality into a method that you call from different views. Thus the code is structured in the opposite direction, instead of a single view with multiple workers, you would have many views. This tends to be what people want anyway, they just aren't used to having the view lookup machinery outside of Pyramid that can call different views based on a query string or anything other predicate for the same physical URL.

I'd suggest you think about how to achieve what you want without attempting to wrap the view. If you're still stuck, pyramid_handlers supports the __action_decorator__ class property which will wrap all views within the handler with the decorator, allowing you to mutate the response before it goes out.

If you have any questions about what I'm talking about, don't hesitate to ask.

--

Michael

Jay T

unread,
Sep 12, 2011, 11:52:08 PM9/12/11
to pylons-...@googlegroups.com
I happened to read your blog :
http://michael.merickel.org/2011/8/23/outgrowing-pyramid-handlers/
I think the match_param view predicate works great for what I really
want to achieve.

I can have one route with multiple views defined and have the request
routed based on the match_param view predicate. Great !

Thanks for your help.

Jay

Michael Merickel

unread,
Sep 13, 2011, 12:54:38 AM9/13/11
to pylons-...@googlegroups.com
No problem. I feel obligated to mention however that pyramid_handlers works fine for this case as well. You can decorate multiple methods with the same "name" but different predicates. For example:

class MyHandler(object):
    def __init__(self, request):
        self.request = request

    @action(name='endpoint', request_method='GET', renderer='string')
    def GET_endpoint(self):
        return 'this is a GET request'

    @action(name='endpoint', request_method='GET',
                 request_param='fmt=json', renderer='json')
    def GET_endpoint_for_json(self):
        return {'key': 'value'}

config.add_handler('api', '/foo/{action}', handler=MyHandler)

/foo/endpoint -> 'this is a GET request'
/foo/endpoint?fmt=json -> '{"key":"value"}'

--

Michael
Reply all
Reply to author
Forward
0 new messages