如何覆盖ore.viewlet.core.FormViewlet中的zope.formlib @ form.action方法

时间:2011-05-21 00:55:25

标签: plone plone-3.x

要点:

  • Plone 3.3.4
  • Products.PloneGetPaid 0.8.8
  • ore.viewlet 0.2.1

我试图覆盖从ore.viewlet.core.FormViewlet继承的viewlet类。它有两个用@form.action修饰的方法(从zope.formlib导入)。我只需要覆盖其中一个。如果我也没有定义另一个,则其操作不可用。所以我定义了它,试图简单地传递父类的返回值。但后来我得到了TypeError: 'Action' object is not callable

详细说明:

具体来说,我重写了Products.PloneGetPaid.browser.cart.ShoppingCartActions,其定义如下:

class ShoppingCartActions( FormViewlet ):

我定义了重写类来继承它。两种装饰方法是:

@form.action(_("Continue Shopping"), name='continue-shopping')
def handle_continue_shopping( self, action, data ):

@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):

我真的只关心压倒第一个。我想留下另一个人。这两个@ form.action方法在Shopping Cart Management页面的“Next Steps”视图中生成“Continue Shopping”和“Checkout”按钮。如果我只在子类中定义“继续购物”方法,则“结帐”按钮会消失。所以我尝试像这样定义Checkout方法:

@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):
    return super( ShoppingCartActions, self ).handle_checkout(action, data)

但后来我收到了这个错误:

2011-05-20 17:01:40 ERROR Zope.SiteErrorLog http://localhost:8080/obrien/@@getpaid-cartTraceback (innermost last):
  Module ZPublisher.Publish, line 119, in publish
  Module ZPublisher.mapply, line 88, in mapply
  Module ZPublisher.Publish, line 42, in call_object
  Module Products.PloneGetPaid.browser.cart, line 46, in __call__
  Module zope.viewlet.manager, line 104, in update
  Module ore.viewlet.core, line 15, in update
  Module Products.PloneGetPaid._patch, line 44, in update
  Module zope.formlib.form, line 750, in update
  Module zope.formlib.form, line 594, in success
  Module plonetheme.obrienskin.browser.cart, line 23, in handle_checkout
TypeError: 'Action' object is not callable

这让我觉得必须有一些技巧来覆盖和继承用@form.action修饰的方法。

任何提示都会受到赞赏。

谢谢!

2 个答案:

答案 0 :(得分:3)

@form.action将方法包装到form.Action实例中,并将其绑定到success_handler属性。所以你的代码应该是这样的:

@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):
    return super(ShoppingCartActions, self).handle_checkout.success_handler(
        self, action, data)

答案 1 :(得分:0)

也许这比使用装饰

更具问题

'super'的一个大问题是它听起来会导致超类的方法副本被调用。事实并非如此,它会导致调用MRO中的下一个方法。

这种误解会导致人们犯两个常见的错误。

  1. 如果唯一的超类是'object',那么人们会忽略对super(...)。 init 的调用,毕竟,对象。 init 不会什么!但是,这是非常不正确的。这样做会导致不调用其他类的 init 方法。
  2. 人们认为他们知道他们的方法会得到什么参数,以及他们应该传递给super的论据。这也是不正确的。
  3. http://fuhm.net/super-harmful/

    Personnaly我没有任何问题要覆盖例如    ShoppingCartAddItem中的@ form.action(_(“Update”),condition =“isNotEmpty”) 我不是专家,这些修改都很老了...... 我只是做了我的更改,只留下剩下的代码而不使用super ......如果你知道我想要的意思......