如何从 Python Django 中的表单实例创建表单集
How to create a formset from form-instance in Python Django
我正在尝试从表单实例中获取 Django - Formset class。
在我的表单 class 中,我在 init 方法中添加了一些字段,因为表单必须提供一些灵活性。因此我不能将 class 作为参数传递给 formset_factory 函数。
--forms.py
class ConfigForm(forms.Form):
def __init__(self, fields, fields_choices, *args, **kwargs):
super(ConfigForm, self).__init__(*args, **kwargs)
for field in fields:
# instanciate Field from field data
exec(
f'self.fields["{field.name}"] ='
f'forms.{field.field_type.field_type}('
f'required = {field.required},'
f'disabled = {field.disabled},'
f'label = "{field.label}",'
f'initial = "{field.value}",'
f'widget = {field.widget},'
f'help_text = "{field.description}"'
f')'
)
# if field is a ChoiceField add choices to the field instance
if 'ChoiceField' in field.field_type.field_type:
self.fields[field.name].choices = [fields_choices[field.name]]
--views.py
...
form = forms.ConfigForm(active_fields, field_choices)
formset = formset_factory(form, extra=1)
...
但是如果我尝试使用 ConfigForm 实例调用 formset_factory,则会发生以下错误:
Internal Server Error: /machines/testconfig/mw0-sap-001/
Traceback (most recent call last):
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "D:\Users\BKU\maximilianwiederer\OneDrive - Deutsche Bahn\Documents\Programmierung\Eclipse\sap4cloud-dev\machines\views.py", line 83, in get
formset = forms.formset_factory(form, extra=1)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\formsets.py", line 441, in formset_factory
return type(form.__name__ + 'FormSet', (formset,), attrs)
AttributeError: 'ConfigForm' object has no attribute '__name__'
您不能将表单实例传递到表单集工厂。它需要一个 class,而不是一个实例。但是,您可以向工厂提供一个参数字典,以提供给创建的每个表单实例。
以下是我建议您编写代码的方式。
ConfigFormset = forms.formset_factory(forms.ConfigForm)
formset = ConfigFormset(
form_kwargs={
'fields' : active_fields,
'fields_choices': {}
}
)
我正在尝试从表单实例中获取 Django - Formset class。
在我的表单 class 中,我在 init 方法中添加了一些字段,因为表单必须提供一些灵活性。因此我不能将 class 作为参数传递给 formset_factory 函数。
--forms.py
class ConfigForm(forms.Form):
def __init__(self, fields, fields_choices, *args, **kwargs):
super(ConfigForm, self).__init__(*args, **kwargs)
for field in fields:
# instanciate Field from field data
exec(
f'self.fields["{field.name}"] ='
f'forms.{field.field_type.field_type}('
f'required = {field.required},'
f'disabled = {field.disabled},'
f'label = "{field.label}",'
f'initial = "{field.value}",'
f'widget = {field.widget},'
f'help_text = "{field.description}"'
f')'
)
# if field is a ChoiceField add choices to the field instance
if 'ChoiceField' in field.field_type.field_type:
self.fields[field.name].choices = [fields_choices[field.name]]
--views.py ...
form = forms.ConfigForm(active_fields, field_choices)
formset = formset_factory(form, extra=1)
...
但是如果我尝试使用 ConfigForm 实例调用 formset_factory,则会发生以下错误:
Internal Server Error: /machines/testconfig/mw0-sap-001/
Traceback (most recent call last):
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\views\generic\base.py", line 71, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\views\generic\base.py", line 97, in dispatch
return handler(request, *args, **kwargs)
File "D:\Users\BKU\maximilianwiederer\OneDrive - Deutsche Bahn\Documents\Programmierung\Eclipse\sap4cloud-dev\machines\views.py", line 83, in get
formset = forms.formset_factory(form, extra=1)
File "C:\Users\maximilianwiederer\AppData\Local\Programs\Python\Python37\lib\site-packages\django\forms\formsets.py", line 441, in formset_factory
return type(form.__name__ + 'FormSet', (formset,), attrs)
AttributeError: 'ConfigForm' object has no attribute '__name__'
您不能将表单实例传递到表单集工厂。它需要一个 class,而不是一个实例。但是,您可以向工厂提供一个参数字典,以提供给创建的每个表单实例。
以下是我建议您编写代码的方式。
ConfigFormset = forms.formset_factory(forms.ConfigForm)
formset = ConfigFormset(
form_kwargs={
'fields' : active_fields,
'fields_choices': {}
}
)