Ways of preserving form data in a multiple form view.

Is there a way to preserve the data of one form (in a multiple form view) when another form is submitted to the same page ?

Can you be a little more specific and provide more details as to what you’re trying to do here?

What exactly do you mean by “preserve the data”?

Are you talking about multiple Django forms being rendered within one form tag? Or are you talking about multiple Django forms, each being rendered within the same form tag?

Let’s say I have two independent forms, form1 and form2 each having it’s own form tag, rendered by Django. Let’s imagine form1 is empty and we enter some inputs in form2, we submit the form2 data to the same page. Now let’s enter some inputs in form1 and again submit to the same page. In doing so, I loose the form input data in form2. How do I prevent it ?

First, we need to make sure we’re clear on some terminology as far as Django is concerned.
When you submit a form, you’re not “submitting to a page” - you’re submitting to a view. The view processes that submittal and returns some kind of response. (It could be either another page or it could be JSON.)

So, when you have a form, with a submit button, it’s going to POST data from the page to a view. Each form is going to post its own data. Form 1 is not going to submit the data from Form 2.

When the form has been submitted, and the view is preparing the response, it’s the responsibility of the view to get all the pertinent data for the page being returned. So if the view handling the submission of Form1 is returning a page containing both form1 and form2, that view needs to retrieve whatever data was previously submitted for form2 and prepopulate those form fields with it.

In short, I need a way to do this :slightly_smiling_face: Any pointers ?

The Working with Forms docs are the best place to start, followed by the Forms API page.

I went through (read skimmed) the docs but nothing immediately jumped at me as a way to do it.

Here’s a short pseudo code of the View in question. Since the request.POST contains data only for the submitted form.

class SomeView(View):

    def get(self, request, *args, **kwargs):
        # Render the main_view.html with form1 & form2 instances.

    def post(self, request, *args, **kwargs):
        form1 = Form1(request.POST)
        form2 = Form2(request.POST)
        # Construct context with form instances
        if form1.is_valid():
            # Some processing of the cleaned data
            return render(
                request,
                "main_view.html",
                context
            )        
        if form2.is_valid():
            # Some processing of the cleaned data
            return render(
                request,
                "main_view.html",
                context
            )            
        return render(
            request,
            "main_view.html",
            context
        )

That is correct - the post is only going to have the data from the form being posted.

So before you render your view, you’ll need to retrieve the data from your database from the other form and include that in your context to be rendered. (Or, what might be better would be when you create the other form, use the existing data for the initial values.)

(Note: For this type of situation, there’s also something to be said for having two views, one for each form. That way your view doesn’t have to have a bunch of if statements to figure out which form is being submitted.)

Yeah, I realized I could also use multiple views that render the same template. Would be cleaner.

I should have clarified before that I am not using any database. The data is not persisted anywhere.

If that is literally true, then your only other alternative is to not render entire pages. You’d have to write some JavaScript to submit the data from an individual form and only render either data or a returned HTML fragment from the view, because the data isn’t persisted in the browser, either.

But given that Django relies upon a database for its internal functions, I find it difficult to believe that you’re doing this without any database. It’s not a big deal to throw one or two tables in there for that type of purpose. (I’ve got a similar situation where the database just acts like a session cache. There’s no long-term storage of data, it’s just a place to hold intermediate values while information is being gathered across multiple forms.)

You could also persist the data on the server in the session object.

Thank you for your help. I look at the options you have provided. When I said I am not using a database, I meant I am not explicitly storing the form data anywhere.

Bit late, but I’ll add what I did.

I ran into same - I have a first form for ‘search settings’ in a certain page, and another form that submits inputs for the actual search. I could craft a single form probably, but the second form has a javascript structure-input widget that needs some handling, and life is too short.

I solved it by specifically passing on the settings in the url, when the first form is posted, resubmitting same page, and picking them up in the form1.init(var1, var2,…) for initialising these form1 fields. This was doable as there were only a few simple boolean and numeric settings. It’s not pretty.

I will be looking at storing them in the session object though for another two-form case. The drawback there is bloating, but it should be fine for small amounts of data.