如果在Pyramid中配置了类的视图,是否可以使用为超类配置的视图?

时间:2013-02-14 09:08:06

标签: python inheritance pyramid

我正在创建一个使用遍历的基于金字塔的简单CMS。有一个名为Collection的类,它有一些子类,如NewsCollectionGalleriesCollection等。

我需要两种视图来显示这些集合。 frontent,html视图和后端json视图(管理面板使用dgrid显示数据)。后端视图可以是通用的 - 它会在每种情况下转储json数据。前端视图不应该 - 每种数据都会有一个自定义模板。

问题是:当我配置这样的视图时:

@view_config(context=Collection, xhr=True, renderer='json', accept='application/json')

它正常工作。但是,只要我添加为NewsCollection配置的任何视图,此视图就会优先。即使我特意将谓词与上述配置冲突(例如accept='text/html'),仍然不会调用上面的视图。相反,我会得到一个“谓词不匹配”。

我的问题是 - 如果还有Collection的观看次数,我是否可以执行任何操作来调用为NewsCollection配置的视图?或者我是否必须使用其他设计(例如 url dispatch 或为不同的资源类型多次添加相同的视图)

1 个答案:

答案 0 :(得分:6)

我试图构建一个非常相似的系统并发现同样的问题 - 事实上,这是Pyramid bug跟踪器中的票证:https://github.com/Pylons/pyramid/issues/409

简而言之,并非金字塔中的所有视图谓词都相同 - context是一种特殊情况。首先使用context匹配视图,然后使用其他谓词缩小选择范围。

还有一个最近的pull request会让金字塔表现得像你(和我)所期望的那样 - 然而,从讨论中我看到,由于可能的性能权衡,它不太可能被采用。

更新:拉动请求已于2013年3月合并,所以我猜它应该可以在1.4版本之后发布)

解决方法是使用自定义谓词:

def context_implements(*types):
    """
    A custom predicate to implement matching views to resources which
    implement more than one interface - in this situation Pyramid has
    trouble matching views to the second registered interface. See
    https://github.com/Pylons/pyramid/issues/409#issuecomment-3578518

    Accepts a list of interfaces - if ANY of them are implemented the function
    returns True
    """
    def inner(context, request):
        for typ in types:
            if typ.providedBy(context):
                return True
        return False
    return inner


@view_config(context=ICollection,
    custom_predicates=(context_implements(INewsCollection),)
    )
def news_collection_view(context, request):
    ....