2

I am trying to get a Django - Formset out of an instance of a form class.

In my form class i add some fields in the init method because the form has to offer some flexibility. Therefore i can't pass the class as parameter to the formset_factory function.

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

...

But if i try to call formset_factory with an instance of ConfigForm, the following error occurs:

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__'
0

1 Answer 1

1

You can't pass an instance of a form into a formset factory. It expects a class, not an instance. However, you can provide a dictionary of arguments to the factory to give to each instance of the form that is created.

https://docs.djangoproject.com/en/2.2/topics/forms/formsets/#passing-custom-parameters-to-formset-forms

Here's how I would suggest writing your code.

ConfigFormset = forms.formset_factory(forms.ConfigForm)
formset = ConfigFormset(
    form_kwargs={
        'fields' : active_fields,
        'fields_choices': {}
        }
    )
Sign up to request clarification or add additional context in comments.

1 Comment

Thank's, you saved my day. I edited your code because you forgot one step (instanciating the ConfigFormSet and after that get the formset with the form_kwargs out of it) But now everything works fine :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.