Django 1.1 FormWizard,动态扩展表单

时间:2009-12-26 15:05:17

标签: python django forms wizard

我正在尝试创建一个多页表单,其中第二页上的字段元素数由第一页上给出的答案定义。

我有一个formWizard设置,我的理解是我需要使用process_step()来改变下一页的设置。我可以扩展现有的表单定义以添加更多元素,或者将两个或更多表单定义合并在一起以生成正确数量的表单元素,但我不知道如何执行此操作。

例如

第1页 - 选择感兴趣的科目:

Page 2 - 针对每个主题:提出相关问题。问题在应用程序中定义为单独的表单,但需要在一个页面上显示,或合并为一个表单。

任何有用的帮助。

彭德

2 个答案:

答案 0 :(得分:1)

彭德,

至少目前我不知道在FormWizard中将多个表单合并到一个页面的方法。在django 1.2中,您可以将FormSet作为FormWizards中的步骤(按this ticket)包含在内,但这些只处理相同形式的多个副本,而不是多种形式的汇编。但有一种方法可以做你所要求的:

from django.contrib.formtools.wizard import FormWizard
from django import forms

class SubjectForm(forms.Form):
    subjects = forms.MultipleChoiceField(choices = (('language', 'language'), 
                                                        ('sport','sport')))

class RelatedQForm(forms.Form):
    """Overload the __init__ operator to take a list of forms as the first input and generate the 
    fields that way."""
    def __init__(self, interested_subjects, *args, **kwargs):
        super(RelatedQForm, self).__init__(*args, **kwargs)
        for sub in interested_subjects:
            self.field[sub] = forms.CharField(label = "What do you think about %s" % subject)

class SubjectWizard(FormWizard):
    def done(self, request, form_list):
        process_form_list(form_list)

    def process_step(self, request, form, step):
        if step == 1:
            chosen_subs = form.cleaned_data['subjects']
            self.form_list[1] = RelatedQForm(chosen_subs)

使用此代码,您可以像在视图中一样实例化FormWizard,然后让向导类处理幕后的所有内容。

一般的想法是重载“RelatedQForm”的 init 类来动态地改变字段。此代码段取自here。您可以将 init 运算符中的处理视为您想要的复杂处理,请阅读“将表单中的字段包含为for-loop中的if-elif块”......您甚至可能找出一种以编程方式从当前表单中删除字段的方法,但我必须看到它们才能弄明白。

您的“process_form_list”函数需要使用以下内容循环遍历字段:

for field, val in form.cleaned_data.items():
    do_stuff

希望这可以帮助你:)

答案 1 :(得分:0)

我不认为

self.form_list[1] = RelatedQForm(chosen_subs)

部分有效。我总是收到错误消息:

object is not callable

似乎form_list只接受RelatedQForm(表单的名称),而不是它的实例。