使用@view_defaults和@view_config装饰器进行金字塔视图类继承

neR*_*Rok 5 pyramid

我编写了一个视图类,它有多个@ view_config,并为单个路由设置了谓词.然后我有一个子类来覆盖一些子函数,这会影响视图的制作方式.下面是类似的,但使用简化的代码.

访问view_a路线时,一切正常.访问view_b路径时,显示"404 Not Founds找不到资源".

似乎@view_configs不是'继承'并且链接到新的@view_default.有没有一种简单的方法来解决这个问题,还是我必须切换到手动操作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'
Run Code Online (Sandbox Code Playgroud)

X-I*_*nce 9

@view_config是一个venusian装饰,而不是严格的传统装饰.直到.scan()被召唤才会生效.

这也意味着它们不是继承的,但是venusian提供了一个名为deco的类装饰器lift(),它将完全按照您的意愿执行.

venusian API文档表明,类似于下面的东西应该为你的使用情况的工作:

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'
Run Code Online (Sandbox Code Playgroud)

此时,所有继承的函数都将正确@view_config应用.现在运行.scan()您的应用程序将按预期运行.


请注意,@view_defaults未来的继承可能会发生变化:https://github.com/Pylons/pyramid/issues/1382.

这可能会也可能不会更改您列出的视图,具体取决于您是否希望渲染器从超类中继承.