跳过django FormWizard上的步骤

时间:2009-07-01 11:21:27

标签: python django formwizard

我有一个应用程序,其中有一个FormWizard有5个步骤,其中一个只应在满足某些条件时出现。

该表单适用于在线购物车上的付款向导,其中一个步骤只应显示有可用于piking的促销活动,但是当没有促销时我想跳过该步骤而不是显示为空促销清单。

所以我希望有两种可能的流程:

step1 - step2 - step3

step1 - step3

4 个答案:

答案 0 :(得分:6)

钩子方法process_step()为您提供了这个机会。 验证表单后,您可以修改 self.form_list 变量,并删除不需要的表单。

有人说,如果你的逻辑很复杂,你最好为每个步骤/表单创建单独的视图,并完全放弃FormWizard。

答案 1 :(得分:4)

要使某些表单可选,您可以在urls.py中传递给FormView的表单列表中引入条件:

contact_forms = [ContactForm1, ContactForm2]

urlpatterns = patterns('',
    (r'^contact/$', ContactWizard.as_view(contact_forms,
        condition_dict={'1': show_message_form_condition}
    )),
)

有关完整示例,请参阅Django文档:https://django-formtools.readthedocs.io/en/latest/wizard.html#conditionally-view-skip-specific-steps

答案 2 :(得分:1)

我以其他方式做了,覆盖了render_template方法。我的解决方案。我不知道process_step()......

def render_template(self, request, form, previous_fields, step, context):

    if not step == 0:
        # A workarround to find the type value!
        attr = 'name="0-type" value='
        attr_pos = previous_fields.find(attr) + len(attr)
        val = previous_fields[attr_pos:attr_pos+4]
        type = int(val.split('"')[1])

        if step == 2 and (not type == 1 and not type == 2 and not type == 3):
            form = self.get_form(step+1)
            return super(ProductWizard, self).render_template(request, form, previous_fields, step+1, context)

    return super(ProductWizard, self).render_template(request, form, previous_fields, step, context)

答案 3 :(得分:0)

有多种方法(如其他答案所述),但是我认为可能有用的一种解决方案是覆盖get_form_list()方法:

类似:

from collections import OrderedDict 
def get_form_list(self):

        form_list = OrderedDict()

        // add some condition based on the earlier forms
        cleaned_data = self.get_cleaned_data_for_step('step1') or {}

        for form_key, form_class in self.form_list.items():
            if cleaned_data and cleaned_data['step1'] == 'X':
                 if form_key == 'step2':
                    #skip step2
                    continue
                 else:
                    pass
            elif cleaned_data and cleaned_data['step1'] == 'Y':
                 if form_key == 'step4':
                     #skip step4
                     continue
                 else:
                     pass

              ....
                  
            # try to fetch the value from condition list, by default, the form
            # gets passed to the new list.
            condition = self.condition_dict.get(form_key, True)
            if callable(condition):
                # call the value if needed, passes the current instance.
                condition = condition(self)
            if condition:
                form_list[form_key] = form_class
        return form_list

我认为通过这种方式,您可以处理复杂的表格,并且不会与其他内容发生冲突。