This is my code
def generate_dynamic_formset(app_label, head_model_name, model_configs, instance=None, hide_fields=None, readonly_fields=None):
"""
Generate dynamic forms and formsets based on the provided model configurations.
"""
hide_fields = hide_fields or []
readonly_fields = readonly_fields or []
HeadModel = apps.get_model(app_label=app_label, model_name=head_model_name)
# Dynamically create a form class for the head model with specified fields and Crispy Forms integration
class DynamicHeadForm(modelform_factory(HeadModel, fields=model_configs['head_fields'])):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_method = 'post'
self.helper.form_tag = False # Let the template handle the form tag
if 'password' in self.fields:
self.fields['password'].widget = PasswordInput()
# Apply read-only fields if in edit mode
if instance:
for field in readonly_fields:
if field in self.fields:
self.fields[field].widget.attrs['readonly'] = True
# Hide or clear fields as specified
for field in hide_fields:
if field in self.fields:
self.fields[field].initial = None
self.fields[field].required = False # Make the field optional
def clean(self):
cleaned_data = super().clean()
# Remove hidden fields from cleaned_data
for field in hide_fields:
if field in cleaned_data and cleaned_data[field] == '':
# Ensure the field is not saved if it has an empty value
cleaned_data.pop(field, None)
return cleaned_data
head_form = DynamicHeadForm(instance=instance)
formsets = []
for config in model_configs['body_models']:
BodyModel = apps.get_model(app_label=app_label, model_name=config['model_name'])
fk_field = config['fk_field']
DynamicFormset = inlineformset_factory(
HeadModel,
BodyModel,
fields=config['fields'],
extra=3
)
# Dynamically create a formset with Crispy Forms integration
class DynamicBodyFormset(DynamicFormset):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for form in self.forms:
form.helper = FormHelper()
form.helper.form_method = 'post'
form.helper.form_tag = False # Let the template handle the form tag
# Apply read-only fields to body model forms
if instance:
for field in readonly_fields:
if field in form.fields:
form.fields[field].widget.attrs['readonly'] = True
# Hide or clear fields as specified for body model forms
for field in hide_fields:
if field in form.fields:
form.fields[field].initial = None # Clear the field value
form.fields[field].required = False # Make the field optional
def clean(self):
cleaned_data = super().clean()
for form in self.forms:
form_cleaned_data = form.clean()
# Remove hidden fields from cleaned_data
for field in hide_fields:
if field in form_cleaned_data and form_cleaned_data[field] == '':
# Ensure the field is not saved if it has an empty value
cleaned_data.pop(field, None)
return cleaned_data
formset = DynamicBodyFormset(instance=instance)
formsets.append({'formset': formset, 'fk_field': fk_field})
return head_form, formsets
It does not return 3 extra form. It returns only one form. Please help to fix this.