I’m working on my first real form. I’d like the users to be able to save the form state by clicking on, say, a “Save” button. All data submitted would be saved in the database, users could leave the page and come back to the form later at the same URL, and they would retrieve the data previously entered. Then, by clicking on “Submit”, they would send the final version and wouldn’t be able to modify their submission.
I assume that some kind of cookie would be needed for that.
How could I reach this? What direction do I have to look in?
You’ve got two or three different options, depending precisely upon the implications of what happens to the data being submitted, whether or not people submitting forms are authenticated users, whether they can only fill out this form once or if they could have multiple submissions “in flight”.
For example, you could store the form submission in your table, with a flag indicating whether or not it has been submitted. Your other processing of that data would then be responsible for only processing forms where submitted == False.
Or, if that’s not practical, you could write the form data to a different model - a “holding” model. The view invoked by the submit button is then responsible for copying the data to the appropriate model(s).
It’s a quite basic form, functionally at least. The data being submitted is destined to remain in the database, untouched, until someone extract it to analyse the result. People submitting forms shouldn’t have to authenticate before, but they would be supposed to post only one submission.
Submission is … submission. I mean, that is just what it is. You submit a form, the data gets processed and saved. Since the user is pressing a “Save” button (which is essentially a submit button), the data will be stored in a database. Visiting that data for updates will certainly present the saved state.
What is “final” is your perception. The database only sees records (it does not interpret). So you can indicate that the data is inconclusive by adding a boolean field to the table (like @KenWhitesell advised). The state of that field would determine if the User is done or not.
Alternatively, you can have two tables: one for temporary data, and the other for the final destination. You would have to do clear the temporary table when the final data gets to the destination. You do the logic behind the scenes. The User does not see two tables.
You may try sessions, but that will bring headaches.
In this specific form, there are a lot of questions and answering the form can be quite long, so I’d like the submitters to be able to record their progress and come back later to keep filling up the form.
Edit: keywords here would be “save draft”. It’s the same question expressed here.
Indeed, I get that the data will be saved in the database as a regular submission, and I also get how a boolean field could be used to indicate if the submission is complete or not, but on the frontend level, how could I implement it?
Maybe it happens on the template level, and so it’s not as much a Django related question as a generic HTML one. Apologies for any kind of confusion here
To complete the description of the application: it’s an online survey destined towards a specific group. Each person will want to fill up the survey once, et is not supposed to come back to the survey once it’s done.
I’d like to offer the user the ability to answer only part of the survey and to start where s/he stopped once s/he comes back at the same URL.
If the users are not authenticating to take the poll, you may be looking at “session” (cookies). Once your app determines identity from sessions, the rest of the sieving logic can happen within the views. That should take care of continuity. Otherwise, you are probably overthinking it.
The problem is that sessions are (should be) temporary and they do expire. They can also go away if you close your browser. They’re really not designed for anything other than temporary storage. (They’re also associated with a single system, so if you start your form on “Machine A” and then go to “Machine B”, you’ll have no access to what you started to fill out on “Machine A”.)
By the very strict definition of the term “authenticate”, you don’t need to use a password. (That becomes very weak authentication, but it’s still a type of authentication.) You could have someone enter their name - or any other information that you want - and associate a form with that information. They could then re-enter that information and retrieve the data-supplied-so-far to repopulate the form(s).
From the front-end side, you could do this multiple ways. One of the simplest ways may be:
Home page - ask for their name or id number or whatever, then redirects them to the form page.
Form page - either initializes a new form or retrieves the existing form from the database, based upon what was entered in step 1. This page has two buttons, “Save draft” and “Submit”.
“Save draft” posts the form, saves the data and returns to the form page.
“Submit” posts the form, saves the data, and proceeds to the “success page”.
You can take this solution a little further. Perhaps you may lose the “Save Draft” button completely and have the page save automatically after an input. That will require an onchange event on the input elements.