我使用FormWizard创建了一个两步形式,如下所示:
现在第二种形式取决于第一种形式的输入。一些博客或stackoverflow帖子涵盖了类似的主题,我按照说明操作。 但是,在process_step期间应该保存的变量不适用于下一个_ init _。
如何将变量位置从process_step传达到_ init _?
class reMapStart(forms.Form):
location = forms.CharField()
CHOICES = [(x, x) for x in ("cars", "bikes")]
technology = forms.ChoiceField(choices=CHOICES)
class reMapLocationConfirmation(forms.Form):
def __init__(self, user, *args, **kwargs):
super(reMapLocationConfirmation, self).__init__(*args, **kwargs)
self.fields['locations'] = forms.ChoiceField(widget=RadioSelect(), choices=[(x, x) for x in location])
class reMapData(forms.Form):
capacity = forms.IntegerField()
class reMapWizard(FormWizard):
def process_step(self, request, form, step):
if step == 1:
self.extra_context['location'] = form.cleaned_data['location']
def done(self, request, form_list):
# Send an email or save to the database, or whatever you want with
# form parameters in form_list
return HttpResponseRedirect('/contact/thanks/')
绝对赞赏任何帮助。
谢谢, H
PS:使用较新的代码更新了帖子。
答案 0 :(得分:9)
我认为您可以直接在POST
方法中访问__init__
字典,因为它看起来像向导通过POST
将get_form
传递到每个表单实例中,但是我由于某种原因看不到数据。
我提出的另一种方法是使用render_template
钩子,而不是花太多时间。
class ContactWizard(FormWizard):
def done(selef, request, form_list):
return http.HttpResponse([form.cleaned_data for form in form_list])
def render_template(self, request, form, previous_fields, step, context=None):
"""
The class itself is using hidden fields to pass its state, so
manually grab the location from the hidden fields (step-fieldname)
"""
if step == 2:
locations = Location.objects.filter(location=request.POST.get('1-location'))
form.fields['locations'].choices = [(x, x) for x in locations]
return super(ContactWizard, self).render_template(request, form, previous_fields, step, context)
答案 1 :(得分:6)
您可以使用存储对象从任何步骤获取数据:
self.storage.get_step_data('0')
这将返回保存在该特定步骤的存储后端中的数据字典。
在下面的示例中,第一个表单包含一个'Activity'下拉选择。然后,第二个表单包含一个位置选择小部件,该小部件仅显示可用于该活动的位置。
当你向前或向后通过向导时这是有效的 - 如果按'prev',上面的答案不起作用,因为他们只依靠向导前进(即POST dict将不包含步骤0的数据,如果你按步骤3中的prev!)
def get_form(self, step=None, data=None, files=None):
form = super(EnquiryWizard, self).get_form(step, data, files)
#print self['forms']['0'].cleaned_data
step = step or self.steps.current
if step == '1':
step_0_data = self.storage.get_step_data('0')
activity = Activity.objects.get(pk=step_0_data.get('0-activity'))
locations = Location.objects.filter(activities=activity)
form.fields['locations'].widget = forms.CheckboxSelectMultiple(choices=[(x.pk,x.name) for x in locations])
return form
答案 2 :(得分:1)
工作代码,在用Yuji的帮助(谢谢)解决问题之后是:
class reMapWizard(FormWizard):
def render_template(self, request, form, previous_fields, step, context=None):
if step == 1:
location = request.POST.get('0-location')
address, lat, lng, country = getLocation(location)
form.fields['locations'] = forms.ChoiceField(widget=RadioSelect(), choices = [])
form.fields['locations'].choices = [(x, x) for x in address]
return super(reMapWizard, self).render_template(request, form, previous_fields, step, context)