如何在 ore.viewlet.core.FormViewlet 中重写 zope.formlib @form.action 方法
摘要:
- 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 方法会在购物车管理页面的“后续步骤”视图中生成“继续购物”和“结帐”按钮。如果我只在子类中定义“继续购物”方法,“结账”按钮就会消失。所以我尝试像这样定义 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
装饰的方法。
任何提示将不胜感激。
谢谢!
Summary:
- Plone 3.3.4
- Products.PloneGetPaid 0.8.8
- ore.viewlet 0.2.1
I am trying to override a viewlet class that inherits from ore.viewlet.core.FormViewlet. It has two methods decorated with @form.action
(which is imported from zope.formlib). I need to override only one of them. If I don't define the other one, too, its action is unavailable. So I defined it, trying to simply pass the return value of the parent class. But then I get a TypeError: 'Action' object is not callable
.
Details:
Specifically, I'm overriding Products.PloneGetPaid.browser.cart.ShoppingCartActions, which is defined like this:
class ShoppingCartActions( FormViewlet ):
I defined the overriding class to inherit from this. The two decorated methods are:
@form.action(_("Continue Shopping"), name='continue-shopping')
def handle_continue_shopping( self, action, data ):
and
@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):
I really only care about overriding the first. I'd like to leave the other one alone. These two @form.action methods generate the "Continue Shopping" and "Checkout" buttons in the "Next Steps" viewlet of the Shopping Cart Management page. If I only define the "Continue Shopping" method in my subclass, the "Checkout" button disappears. So I tried defining the Checkout method like this:
@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):
return super( ShoppingCartActions, self ).handle_checkout(action, data)
But then I get this error:
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
This makes me think that there must be some trick to overriding and inheriting methods decorated with @form.action
.
Any tip would be appreciated.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
@form.action
将方法包装到form.Action
实例中,并将其绑定到success_handler
属性。所以你的代码应该是这样的:@form.action
wraps the method into anform.Action
instance and binds it there to thesuccess_handler
attribute. So your code should look like this:也许super的问题比decorate的问题更大。
“super”的一个大问题是,听起来它会导致调用该方法的超类副本。事实并非如此,它会导致调用 MRO 中的下一个方法。
这种误解导致人们犯两个常见的错误。
http://fuhm.net/super-harmful/
我个人没有任何需要覆盖的问题例如
ShoppingCartAddItem 中的 @form.action(_("Update"), condition="isNotEmpty")
我不是专家,这些修改已经很老了......
我只是做了更改,留下了剩余的代码,没有使用 super
...如果你知道我想表达什么...
maybe it is more a problem with super than with decorate
One big problem with 'super' is that it sounds like it will cause the superclass's copy of the method to be called. This is simply not the case, it causes the next method in the MRO to be called.
That misconception causes people to make two common mistakes.
http://fuhm.net/super-harmful/
Personnaly I didn't have any problem to override for example
@form.action(_("Update"), condition="isNotEmpty") in ShoppingCartAddItem
I am not an expert and these modifications are quite old ...
I just made my changes leaving alone the remaining code without using super
...if you know what I want to mean...