Django 动态添加的表单字段将在form.u数据中删除

Django 动态添加的表单字段将在form.u数据中删除,django,django-forms,Django,Django Forms,我在模板中加入了一些客户端Javascript,允许用户向表单动态添加字段。我的问题是,这些字段是以形式清理的。已清理的\u data,因此我无法以这种方式访问它们 所有字段都可以在request.POST中访问,因此我可以用它来解决这个问题,但我想用“正确的方法”来解决这个问题,我认为解决方法在于使用django表单,而不是直接读取请求 我尝试重写form.clean(),但数据到达时似乎已经消失了 其他详细信息:我将这些字段命名为fieldname\u x,其中x是一个数字。在request

我在模板中加入了一些客户端Javascript,允许用户向表单动态添加字段。我的问题是,这些字段是以
形式清理的。已清理的\u data
,因此我无法以这种方式访问它们

所有字段都可以在
request.POST
中访问,因此我可以用它来解决这个问题,但我想用“正确的方法”来解决这个问题,我认为解决方法在于使用django表单,而不是直接读取请求

我尝试重写
form.clean()
,但数据到达时似乎已经消失了


其他详细信息:我将这些字段命名为
fieldname\u x
,其中
x
是一个数字。在
request.POST
中,
request.POST['fieldname']
是一个包含所有值的列表,但
表单。已清理的数据只包含每个列表的最后一个值。

您知道这些字段将是什么类型吗?它们只是简单的文本字段吗?我做过类似的事情,创建动态表单

# make sure these exist by examining request.POST
custom_fields = ['fieldname_1', 'fieldname_2']

attrs = dict((field, forms.CharField(max_length=100, required=False)) 
             for field in custom_fields)
DynamicForm = type("DynamicForm", (YourBaseForm,), attrs)
submitted_form = DynamicForm(request.POST)
您提交的表单现在应该包含您需要的所有字段及其值。您可能希望删除required=False,但这取决于您自己

这样做的目的是执行基本表单的动态子类,将属性作为属性传递到类定义中。因此,当您使用post数据创建实例时,应该正确映射它们

<input type='text' name='fieldname_1' value='value_for_field_1' /> 
编辑:

我把问题看得更仔细一点。您要做的是确保动态输入元素的命名正确,并且一旦到达django,值就会映射到这些字段名。否则,request.POST将无法正确填写表单

<input type='text' name='fieldname_1' value='value_for_field_1' /> 


etc

我正在我目前正在做的项目中做这件事。您将需要查看表单集。但请注意,这并不漂亮。您必须修改存储到表单计数的这个愚蠢的隐藏字段,并且必须正确重命名输入。。这涉及到很多无意义的字符串解析。如果他们使用了数组,比如PHP,就不会有问题了,但他们执意要让我的生活变得悲惨漫无目的地闲逛

编辑:
他们提供这一点,让你的生活少5%的痛苦。。。您只需在前缀上查找并替换相应的数字即可。。但是我想我遇到了一个问题,如果使用post数据初始化表单,则空表单不包含正确的默认值,因此我必须创建一个没有post数据的第二个实例到一个实际为空的表单,这只是延迟了。

也可以在表单文件中执行此操作,这里是Jacob Kaplan Mosse关于动态形式的一个很好的演示:这非常适用于这个问题

所做的是向表单类添加一个方法,该方法添加额外的动态字段,然后从clean中生成信息,以便您可以在视图中获取该信息

class MyForm(forms.Form):
    text = forms.CharField(max_length=30)

    def __init__(self, *args, **kwargs):
        extra = kwargs.pop('extra')
        super(MyForm, self).__init__(*args, **kwargs)

        for i, question in enumerate(extra):
            self.fields['fieldname_%s' % i] = forms.CharField(label=question)

    def extra_fields(self):
        for name, value in self.cleaned_data.items():
            if name.startswith('fieldname_'):
                yield (self.fields[name].label, value)
从视图中调用它:

def doSomething(request, extra_fields):
    form = MyForm(request.POST or None, extra=extra_fields)
    if form.is_valid():
        for (question, answer) in form.extra_answers():
            save_answer(request, question, answer)
        return redirect("create_user_success")

return render_to_response("template/form.html", {'form': form})

非常好,祝贺雅各布·卡普兰·莫斯(Jacob Kaplan Moss)

拉尔夫,我建议你已经走了很长的路。利用python和Django系统做事情。根据需要动态创建模型和表单。看看我的答案。你的“杠杆python”和“Django”是不一致的。您当然利用了Python的动态性,但我采用了Django的方式。他们专门把
empty\u form
放在那里,这样你就可以在JS脚本中使用它,并将表单/字段添加到表单集中,所以我就是这样做的。我将空表单描述解释为允许javascript向表单集中添加额外表单,而不是向表单中添加额外字段。你自己说过,你这样做是痛苦的,涉及大量的字符串处理,只是简单的不好。我的解决方案是4行代码,非常容易维护。@Josh:如果需要,可以在表单集中放置一个字段。不管怎样,我给了你+1。