我有一个应用程序,其中有一个包含 5 个步骤的 FormWizard,其中一个应该只在满足某些条件时出现。
该表格适用于在线购物车上的付款向导,其中一个步骤应仅在有促销活动可供选择时显示,但当没有促销活动时,我想跳过该步骤而不是显示一个空的促销列表.
所以我想有2个可能的流程:
step1 - step2 - step3
step1 - step3
我有一个应用程序,其中有一个包含 5 个步骤的 FormWizard,其中一个应该只在满足某些条件时出现。
该表格适用于在线购物车上的付款向导,其中一个步骤应仅在有促销活动可供选择时显示,但当没有促销活动时,我想跳过该步骤而不是显示一个空的促销列表.
所以我想有2个可能的流程:
step1 - step2 - step3
step1 - step3
钩子方法process_step()正是为您提供了这个机会。验证表单后,您可以修改self.form_list变量,并删除不需要的表单。
不用说,如果您的逻辑非常复杂,最好为每个步骤/表单创建单独的视图,并完全放弃 FormWizard。
要使某些表单可选,您可以在传递给 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
我以另一种方式做到了,覆盖了 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)
有不同的方法(如其他答案中所述),但我认为可能有用的一种解决方案是覆盖该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
我认为通过这种方式您可以处理复杂的表格,并且您不会与其他内容发生任何冲突。