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

时间:2014-11-04 06:09:09

标签: pyramid

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

访问view_a路线时,一切正常。访问view_b路径时,显示“404 Not Found无法找到资源”。

似乎@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'

1 个答案:

答案 0 :(得分:9)

@view_configvenusian装饰者,而不是严格的传统装饰者。直到.scan()被调用才会生效。

这也意味着它们不会被继承,但是venusian提供了一个名为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'

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


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

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