Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyramid view class inheritance with @view_defaults and @view_config decorators

Tags:

pyramid

I have written up a view class that has multiple @view_config's with predicates set for a single route. I then have a subclass that overwrites a couple of the sub-functions, which affects how the view is made. Below is something similar, but with simplified code.

When visiting the view_a route, everything works fine. When visiting the view_b route, it shows "404 Not Found The resource could not be found".

It seems the @view_configs aren't 'inherited' and linked to the new @view_default. Is there a simple way to fix this, or will I have to switch to manually doing config.add_view()?

@view_defaults(route_name='view_a', renderer='templates/views.mak')
class View_A(object):

    def message(self):
        return 'This is view a'

    @view_config(request_method='GET')
    def get(self):
        return {'message': self.message()}

@view_defaults(route_name='view_b')
class View_B(View_A):

    def message(self):
        return 'This is view b'
like image 544
neRok Avatar asked Nov 04 '14 06:11

neRok


1 Answers

@view_config is a venusian decorator, and not a strictly traditional decorator. Not until .scan() is called will anything take effect.

This also means that they are not inherited, however venusian provides a class decorator named lift() that will do exactly as you wish.

The venusian API documentation shows that something like the following should work for your use case:

from venusian import lift

@view_defaults(route_name='view_a', renderer='templates/views.mak')
class View_A(object):

    def message(self):
        return 'This is view a'

    @view_config(request_method='GET')
    def get(self):
        return {'message': self.message()}

@view_defaults(route_name='view_b')
@lift()
class View_B(View_A):

    def message(self):
        return 'This is view b'

At this point all your inherited functions will correctly have the @view_config applied. Now upon running .scan() your application will behave as expected.


Do note, that the inheritance of @view_defaults may change in the future: https://github.com/Pylons/pyramid/issues/1382.

This may or may not change your views as listed, depending on whether you expect the renderer to carry over from the super class.

like image 107
X-Istence Avatar answered Sep 20 '22 07:09

X-Istence