Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling multiple forms in one step #272

Open
marcinkaczmarek10 opened this issue Apr 4, 2024 · 1 comment
Open

Handling multiple forms in one step #272

marcinkaczmarek10 opened this issue Apr 4, 2024 · 1 comment

Comments

@marcinkaczmarek10
Copy link

Is there a proper way to handle multiple forms in one step in a wizard, e.g. MultipleFormWizardView, which would accept a sublist of forms for each step. Was this considered an additional feature in the future?

@rlalik
Copy link

rlalik commented May 28, 2024

Perhaps not the best solution, but currently I am working on a project where I need to combine several forms into one form. Here is my solutions:

class AggregateForm(forms.Form):
    """
    """

    template_name = "aggregate_form.html"

    # extra field to accecp this combination of forms
    confirm_actions = forms.BooleanField(
        label="Confirm these actions",
        required=False,
        initial=True,
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        initial = kwargs.get("initial")

        def update_widgets(name, form, template=None, extras=None):
            if extras is None:
                extras = {}

            new_form = form(prefix=self.prefix, initial=initial[f"{name}_data"], **extras)
            if template:
                new_form.template_name = template
            setattr(self, f"{name}_form", new_form)

        update_widgets(
            "form1",            # some label for form, should be the same like in the initial dictionary
            Form1,              # Form1 is a model form
            "form1_view.html",  # template for this form
            extras={},          # extra parameters for form
        )

        update_widgets(
            "form2",
            Form2,
            "form2_view.html",
            extras={},
        )


AggregateFormSet = forms.formset_factory(AggregateForm, extra=0)

and in the view, in the get_form_initial():

from django.forms.models import model_to_dict

#...

    def get_form_initial(self, step):
        if step == "the_step":
            initials = []
            for ...:  # collect initial data
                initials.append(
                    {
                        "form1_data": model_to_dict(model1_obj), # label plus "_data" suffix
                        "form2_data": model_to_dict(model1_obj),
                    }

            return initials

        return self.initial_dict.get(step, {})

and finally in the master template aggregate_form.html:

...
{{ form.form1_form }}
{{ form.form2_form }}
...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants