如何在 ore.viewlet.core.FormViewlet 中重写 zope.formlib @form.action 方法

发布于 2024-11-09 11:52:34 字数 2195 浏览 0 评论 0原文

摘要:

  • 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡の花香 2024-11-16 11:52:34

@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)

@form.action wraps the method into an form.Action instance and binds it there to the success_handler attribute. So your code should look like this:

@form.action(_("Checkout"), condition="doesCartContainItems", name="Checkout")
def handle_checkout( self, action, data ):
    return super(ShoppingCartActions, self).handle_checkout.success_handler(
        self, action, data)
-柠檬树下少年和吉他 2024-11-16 11:52:34

也许super的问题比decorate的问题更大。

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

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

  1. 如果唯一的超类是“object”,人们会省略对 super(...).init 的调用,因为毕竟 object.init 不执行任何操作!然而,这是非常不正确的。这样做会导致其他类的 init 方法无法被调用。
  2. 人们认为他们知道他们的方法会得到什么参数,以及他们应该将什么参数传递给 super。这也是不正确的。

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.

  1. People omit calls to super(...).init if the only superclass is 'object', as, after all, object.init doesn't do anything! However, this is very incorrect. Doing so will cause other classes' init methods to not be called.
  2. People think they know what arguments their method will get, and what arguments they should pass along to super. This is also incorrect.

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文