Django动态表单示例

时间:2011-05-27 15:39:43

标签: django django-forms django-views

我有一个简单的要求在Django中创建一个动态表单 - 我见过很多例子,但它们似乎不完整,或者需要比我更广泛的Python和Django知识!没有显示应该如何调用示例的动态部分:

这是Q1和Q2的表单类 - 我在表单上放置一个按钮来添加另一个 字段称为Q3 - 然后Q4如果再次按下:我认为我的 init 函数半正确:

class testform(forms.Form):
    Q1 = forms.CharField()
    Q2 = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(testform,self).__init__(*args,**kwargs)
        self.fields['Q%s'%i] = forms.CharField(label='Q%i' % i)

我想在表单上放置一个按钮来添加另一个按钮 字段称为Q3,然后再次按下Q4。

  • 如何从视图中调用_ init _function来添加这些字段?
  • 如果我使用Javascript动态添加字段,如何调用 init 以便在POST表单时能够正确验证Django?

2 个答案:

答案 0 :(得分:9)

回答您的问题:每当您初始化表单时,它都会调用 init ()。例如:form = testform()。这会初始化您的表单。我在这里要做的是添加一些javascript来创建这些新字段。我不确定你对javascript有多熟悉,但我会假设你可以自己解决这个问题。

至于验证,可以在表格中完成。首先,您要告诉它您已使用init()添加了更多字段。

class TestCharField(forms.CharField):
    def __init__(self, *args, **kwargs):
        super(TestCharField, self).__init__(*args, **kwargs) # Needs * and **
    def clean(self, value):
        super(TestCharField, self).clean(value)
        # Do custom validation in here
        return value

class testform(forms.Form):
    def __init__(self, *args, **kwargs):
        super(testform, self).__init__(args, kwargs)

        # args should be a list with the single QueryDict (GET or POST dict)
        # that you passed it
        for k,v in args[0].items():
            if k.startswith('Q') and k not in self.fields.keys():
                self.fields[k] = TestCharField(initial=v, required=True)

您可以随意命名您的字段,它不一定是TestCharField。只需确保在两个地方重命名。这将允许您根据需要创建任意数量的字段。如果这对您不起作用,请告诉我。

答案 1 :(得分:-12)

[编辑] 这不是最好的答案,布莱斯的答案要好得多。我从字面上解决了这个问题并为4个领域提供了解决方案,其中一个非常动态的形式将是一个更优雅的解决方案。

请看看布莱斯的回答。


我想我会用所有可能的字段定义表单并使用javascript隐藏/显示它们:

class testform(forms.Form)
    Q1 = forms.CharField()
    Q2 = forms.CharField()
    Q3 = forms.CharField()
    Q4 = forms.CharField()

HTML:

<table>
  {{ testform.as_table }}
</table>
...
<script type="text/javascript">
    $(function(){
        $('input[name="q3"]').closest('tr').hide();
        $('input[name="q4"]').closest('tr').hide();
    });
</script>

(使用JQuery)
并以类似方式使用按钮显示字段。