2017-10-13 102 views
1

我創建了被添加到self.fields__init__功能這樣的多個動態域(無級屬性)形式負載形式:Django的:用動態字段

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被調用時,我不知道如何加載領域之後手動。想法?

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) 
+0

是字段鍵總是指向相同的字段類型? – grrrrrr

+0

不,字段類型可以是每個有效的django字段類型 – Henhuy

回答

1

你可以調用super__init__之前更新base_fields。此外,is_bound屬性已被設置爲通過is_valid()方法來驗證形式:

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 {} 

但我不太清楚,如果這是正確的解決辦法?

+0

這樣做的竅門!調用'custom = CustomForm(dynamic_fields,request.POST)'後,我可以繼續調用'custom.is_valid()'並通過'custum.cleaned_data'獲取數據。謝謝! – Henhuy

+0

剛發現如果您在一個頁面上使用多個「CustomForms」,則您的解決方案無法正常工作。這是因爲'base_fields'是類屬性。因此,更改它會更改** all **'CustomForms'的字段,從而導致每種形式的字段副本。 – Henhuy

+0

當然,解決方案相當不好。但我認爲這正是你想要做的事情的本質。在'BaseForm'的'__init__'中'fields'屬性是通過複製'self.base_fields'創建的。 所以我想在'update'調用之前在'CustomForm''' init'中創建'self.base_fields'的副本,並在調用'super's'init'之後重置'self.base_fields'應該做的訣竅 – lmr2391

0

對我來說它的工作從Form類只設置數據屬性,類似於Form__init__功能: