摘要:
- 普隆 3.3.4
- 产品.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 方法会在购物车管理页面的"后续步骤"视图中生成"继续购物"和"结帐"按钮。 如果我只在我的子类中定义"继续购物"方法,"结帐"按钮就会消失。 所以我尝试像这样定义结帐方法:
@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
装饰的方法。
任何提示将不胜感激。
谢谢!
@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)
问题比装饰问题更多
"super"的一个大问题是,它听起来会导致调用超类的方法副本。事实并非如此,它会导致调用 MRO 中的下一个方法。
这种误解导致人们犯两个常见的错误。
- 人们省略了对超级(...)的调用。init 如果唯一的超类是"对象",毕竟是对象。初始化什么都不做!但是,这是非常不正确的。这样做将导致不调用其他类的 init 方法。
- 人们认为他们知道他们的方法会得到什么参数,以及他们应该传递给超级。这也是不正确的。
http://fuhm.net/super-harmful/
例如,我没有任何问题可以覆盖 @form.action(_("Update"), condition="isNotEmpty") in ShoppingCartAddItem我不是专家,这些修改很旧......我只是进行了更改,只留下剩余的代码而不使用超级...如果你知道我想说什么...