许多控制器的一个视图(首页)(子视图)

时间:2009-02-22 01:42:11

标签: python model-view-controller pylons cherrypy

注意:无法使用Javascript或iframe。事实上,我不能相信客户端浏览器除了超级基础之外什么都不做。

我正在重建一个传统的PHP4应用程序作为MVC应用程序,我的大部分研究目前都集中在Pylon的框架上。

我遇到的第一个奇怪的问题之一是我过去通过使用iframe或更好的方式解决了javascript正在显示动态的“小部件”集合,就像典型控制器的索引视图的摘要视图

可视化我的问题的最佳方式是查看Google的个性化主页。他们使用Javascript解决了这个问题,但对于我的场景,javascript和基本XHTML以上的任何东西都是不可能的。

我开始研究的一个想法是让我的Frontpage控制器为当前激活的小部件轮询数据库或其他服务,然后获取元组/ dicts列表,动态实例化每个控制器并构建render子列表/ dict查看并将其传递到首页视图,让它解决问题。

所以使用peusudo代码:

Get request goes to WSGI
WSGI calls pylons
Pylons routes to Frontpage.index()
Frontpage.index() 
   myViews = list()
   for WidgetController in ActiveWidegets():
        myViews.append(subRender(WidgetController, widgetView))

c.subviews = myViews
render(frontpage.mako)

有关subRender的奇怪内容

  • 通过__import__动态导入控制器(当前硬编码为项目命名空间:()
  • 有可能非常昂贵(大多数小部件调用可以缓存,但一个是用户面板)

我觉得必须有更好的方法或者可能已经在WSGI中实现的机制或更好的Pylons来实现这一点,但到目前为止,我发现最接近的是这种实用方法:http://www.pylonshq.com/docs/en/0.9.7/modules/controllers_util/#pylons.controllers.util.forward但它为了获得集合视图,在pylons之上构建N pylons实例似乎有点疯狂。

2 个答案:

答案 0 :(得分:6)

虽然在大多数情况下我会推荐你​​最初说的内容,使用Javascript加载每个小部件,因为这不是一个选项,我认为你需要做一些不同的事情。

除了尝试使用单个前端控制器的方法遍历所需的所有小部件并构建它们之外,您可能需要考虑的另一种方法是在Mako中更有效地使用模板。

你可以将小块实际定义为Mako def,它当然具有完整的Python功能。为了避免使用域逻辑污染您的Mako模板,请确保在模型中保留所有模板,并根据需要对Mako def中的模型实例进行调用以构建自身。

这种方法的一个巨大优势是,由于Mako def的支持缓存args,您实际上可以让页面的组件决定如何缓存自己。也许侧边栏应该缓存5分钟,但顶部栏可以改变每个命中例如。此外,由于组件正在触发db命中,因此当组件自行缓存时,您将保存db命中。

ToscaWidgets的性能并没有让它成为一个更大规模的非常可行的选择,所以我不会试图解决这个问题。

对于您现有想法的一些调整,请确保不要将Pylons控制器实际用于“小部件”,因为它们可以根据需要执行更多操作,以支持构建小部件页面所不需要的WSGI。 / p>

我会考虑让所有Widget类都这样工作:

class Widget(object):
    def process(self):
        # Determine if this widget should process a POST aimed at it
        # ie, one of the POST args is a widget id indicating the widget
        # to handle the POST

    def prepare(self):
        # Load data from the database if needed in prep for the render

    def render(self):
        # return the rendered content

    def __call__(self):
        self.process()
        self.prepare()
        return self.render()

然后让您的主要Mako模板遍历窗口小部件实例,并调用它们来渲染它们。

答案 1 :(得分:0)

您可以使用ToscaWidgets来封装您的小部件,以及为每个用户启用的小部件的存储列表(在数据库或其他服务中,如您所建议的那样)。将已启用的ToscaWidgets列表传递给视图,窗口小部件将自行呈现(包括在窗口小部件需要这些资源时动态地向页面添加CSS / JavaScript引用)。