链接z3c形式

时间:2012-05-10 20:54:52

标签: python forms plone z3c.form

我希望能够一个接一个地在Plone中链接几个z3c表单。例如,一旦表单#1完成处理并完成错误检查,它就会将结果(最好是通过GET变量)传递给表单#2,而表单#2反过来形成#3等......我也想成为能够为所有表格使用相同的URL。

我当前的实现是有一个浏览器视图然后调度适当的表单,即DispatcherView检查self.request变量,然后确定表单#1中的哪一个,表单#2,表单#3来调用。

我有这个代码,但似乎z3c表单被抽象为对BrowserView的多次调用,并且尝试触发从它到z3c.form的多次调用会干扰后者的处理。例如,当用户按下“提交”按钮一次时,会发生表单#1的错误检查,当我在下面的示例中尝试解决方案时,表单#2返回显示所有必需字段不正确,这意味着表单#2从形式#1。我尝试从不同的地方触发表单#2,例如DispatcherView(BrowserView)调用()方法,调用()方法形式#1,也更新()和后者的render(),但所有这些覆盖导致同样的问题。

捎带连续调用的适当位置在哪里可以使用,或者我需要创建单独的页面并使用self.request.RESPONSE.redicrect明确地相互重定向?

from Products.Five import BrowserView
from zope import interface, schema
from z3c.form import form, field, group, button
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm

countries = SimpleVocabulary([SimpleTerm(value="not_selected", title=_("Chose your region")),
                            SimpleTerm(value="canada", title=_("Canada")),
                            SimpleTerm(value="us", title=_("United States")),
                            SimpleTerm(value="belgium", title=_("Belgium"))])
products =  SimpleVocabulary([SimpleTerm(value="product1", title=_("Product1")),
                            SimpleTerm(value="product2", title=_("Product2")),
                            SimpleTerm(value="product3", title=_("Product2"))
                            ])
class DispatcherView(BrowserView):
    def __call__(self):
        if 'form.widgets.region' in self.request.keys():
            step2 = Step2(self.context, self.request)
            return step2.__call__()
        else:
            step1 = Step1(self.context, self.request)
            return step1.__call__() 
    def update(self):
        pass

class IStep1(interface.Interface):
    region = schema.Choice(title=_("Select your region"),
                        vocabulary=countries, required=True,
                        default="not_selected")
class IStep2(interface.Interface):
    product = schema.Choice(title=_("Pick a product"),
                        vocabulary=products, required=True)

class Step1(form.Form):
    fields = field.Fields(IStep1)
    def __init__(self,context, request):
        self.ignoreContext = True
        super(self.__class__, self).__init__(context, request)
    def update(self):
        super(self.__class__, self).update()
    @button.buttonAndHandler(u'Next >>')
    def handleNext(self, action):
        data, errors = self.extractData()
        if errors:
            print "Error occured"

class Step2(form.Form):
    fields = field.Fields(IStep2)
    def __init__(self,context, request):
        self.ignoreContext = True
        super(self.__class__, self).__init__(context, request)
    def update(self):
        super(self.__class__, self).update()
    @button.buttonAndHandler(_('<< Previous'))
    def handleBack(self, action):
        data, errors = self.extractData()
        if errors:
            print "Error occured"
            #handle input errors here

    @button.buttonAndHandler(_('Next >>'))
    def handleNext(self, action):
        data, errors = self.extractData()
        if errors:
            print "Error occured"

修改 Cris Ewing为此给出了答案,这是示例代码在使用collective.z3cformwizard重写之后的样子:

from zope import schema, interface
from zope.interface import implements
from z3c.form import field, form
from collective.z3cform.wizard import wizard
from plone.z3cform.fieldsets import group
from plone.z3cform.layout import FormWrapper
from Products.statusmessages.interfaces import IStatusMessage
from Products.statusmessages.adapter import _decodeCookieValue

from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from z3c.form.browser.checkbox import CheckBoxFieldWidget

from Products.Five import BrowserView

countries = SimpleVocabulary([SimpleTerm(value="not_selected", title=_("Chose your region")),
                            SimpleTerm(value="belgium", title=_("Belgium")),
                            SimpleTerm(value="canada", title=_("Canada")),
                            SimpleTerm(value="us", title=_("United States")),
                            ])
products = SimpleVocabulary([SimpleTerm(value="product1", title=_("Product1")),
                            SimpleTerm(value="product2", title=_("Product2")),
                            SimpleTerm(value="product3", title=_("Product3")),
                            SimpleTerm(value="product4", title=_("Product4")),
                            SimpleTerm(value="product5", title=_("Product5"))
                            ])
class Step1(wizard.Step):
    prefix = 'one'
    fields = field.Fields(schema.Choice(__name__="region",
                                title=_("Select your region"), vocabulary=countries,
                                required=True, default="not_selected")
                        )
class Step2(wizard.Step):
    prefix = 'two'
    fields = field.Fields(schema.List(__name__="product",
                                value_type=schema.Choice(
                                    title=_("Select your product"),
                                    vocabulary=products),
                                    required=True
                                    )
                        )
    for fv in fields.values():
        fv.widgetFactory = CheckBoxFieldWidget


class WizardForm(wizard.Wizard):
    label= _("Find Product")
    steps = Step1, Step2
    def finish(self):
        ##check answer here
        import pdb; pdb.set_trace()

class DispatcherView(FormWrapper):
    form = WizardForm
    def __init__(self, context, request):
        FormWrapper.__init__(self, context, request)
    def absolute_url(self):
        return '%s/%s' % (self.context.absolute_url(), self.__name__)

另外不要忘记浏览器:在configure.zcml中查看slug:

<browser:page
    name="view"
    for="Products.myproduct.DispatcherView"
    class=".file.DispatcherView"
    permission="zope2.View"
/>

1 个答案:

答案 0 :(得分:3)

我认为你正在寻找这个:

http://pypi.python.org/pypi/collective.z3cform.wizard