Python Django:带有动态字段的加载表单

Python Django:带有动态字段的加载表单,python,django,forms,Python,Django,Forms,我创建了一个具有多个动态字段(无类属性)的表单,这些字段被添加到\uuuu init\uuu函数中的self.fields,如下所示: class CustomForm(django.forms.Form): def __init__(dynamic_fields, *args, **kwargs): super(CustomForm, self).__init__(*args, **kwargs) for name, field in dynamic_f

我创建了一个具有多个动态字段(无类属性)的表单,这些字段被添加到
\uuuu init\uuu
函数中的
self.fields
,如下所示:

class CustomForm(django.forms.Form):
    def __init__(dynamic_fields, *args, **kwargs):
        super(CustomForm, self).__init__(*args, **kwargs)
        for name, field in dynamic_fields.items():
            self.fields[name] = field

dynamic_fields = {'val1': IntegerField(), 'val2': FloatField()}
CustomForm(dynamic_fields)
现在,我不知道如何在
POST
请求后加载表单。通常,我会这样做:

custom_form = CustomForm(request.POST)
if custom_form.is_valid():
    data = custom_form.cleaned_data
    ...

但是由于调用
super
时字段的形式未知,因此我不知道以后如何手动加载字段。想法?

您可以在调用
super
之前更新
基本字段

class CustomForm(django.forms.Form):
    def __init__(dynamic_fields, *args, **kwargs):
        self.base_fields.update(dynamic_fields)
        super(CustomForm, self).__init__(*args, **kwargs)

dynamic_fields = {'val1': IntegerField(), 'val2': FloatField()}
CustomForm(dynamic_fields)

对我来说,只需从
表单
类中设置数据属性就行了,类似于
表单
类的
初始化
函数。此外,必须通过
is\u valid()
方法设置
is\u bound
属性以验证表单:

class CustomForm(django.forms.Form):
    def __init__(dynamic_fields, data=None, *args, **kwargs):
        super(CustomForm, self).__init__(*args, **kwargs)
        for name, field in dynamic_fields.items():
            self.fields[name] = field
        self.is_bound = data is not None
        self.data = data or {}

但我不太确定,这是否是正确的解决方法

字段键总是指向相同的字段类型吗?不,字段类型可以是所有有效的django字段类型。这就成功了!调用
custom=CustomForm(动态字段,request.POST)
后,我可以继续调用
custom.is\u valid()
并通过
custum.cleaned\u data
获取数据。谢谢刚刚发现,如果在一个页面上使用多个
CustomForms
,您的解决方案将无法工作。这是因为
base\u字段
是类属性。因此,更改它会更改所有
CustomForms
的字段,从而导致每个表单中都有字段副本。当然,解决方案相当粗糙。但我认为这是你想做的事情的本质。在
BaseForm`的
\uuuu init\uuuu'中,通过复制
self.base\u字段
来创建
字段
属性。因此,我想在调用
update
之前,在
CustomForm
s
init
中复制
self.base\u字段,并在调用
super
s
init
之后重置它应该可以达到目的