django-viewsdjango-formsdjango-pagination

How to display the previously filled form values?


I have the following view:

    class PaginatedFormsView(View):

    def get(self, request):
        forms = [PatientsForm(), VisitsForm()]

        # Get the current page number from the query string       
        page_number = request.GET.get('page')
  
        # Paginate the forms list
        paginator = Paginator(forms, per_page=1)
        page = paginator.get_page(page_number)


        # Get any previously submitted form data from the session
        form_data = request.session.get('form_data', {})


        # Bind the form data to the forms
        for form in page.object_list:
            if form_data:             
                for field_name, field_value in form_data.items():
                    if field_name in form.fields:                        
                        form.fields[field_name].initial = field_value
            form.is_bound = True
        return render(request, 'main_patients.html', {'page': page})


    def post(self, request):
        forms = [PatientsForm(request.POST), VisitsForm(request.POST)]


        # Process the submitted form data
        for form in forms:
            if form.is_valid():
                # Save the form data to the session
                request.session.setdefault('form_data', {})
                request.session['form_data'].update(form.cleaned_data)
          
  
        # Check if all forms have been submitted
        page_number = request.GET.get('page')
        paginator = Paginator(forms, per_page=1)
        page = paginator.get_page(page_number)

        if page.has_next():
            # Redirect to the next page
            return HttpResponseRedirect('?page=' + str(page.next_page_number()))
        else:
            # All forms have been submitted, redirect to the processing view
            return redirect('whatever_to_be_implemented')

And the following template:

    <div class="content section">
    <form method="POST">
        {% csrf_token %} <!-- an extra measure of security between user and server post/get requests-->
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Form completion</legend>
            {{ page.object_list.0|crispy }}
        </fieldset>
        <div class="form-group">
            {% if page.has_previous %}
                <a class="ml-2" href="?page={{ page.previous_page_number }}" style="text-decoration: none">Previous</a>
            {% endif %}
            {% if page.has_next %}
                <button class="btn btn-outline-info" type="submit">Next</button>
            {% else %}
                <button class="btn btn-outline-info" type="submit">Post</button>
            {% endif %}
        </div>
    </form>
</div>

So I'm having some issues displaying the values from an already filled form when going back to a previous page. Also I've did some manual checks with simple prints for the values before the code hits the rendering function in both get() and post() functions.

At first glance they look fine I guess, but the page(form) is still rendered with empty values. For example "page.object_list[0].fields["gender"].initial" returns that filled value from the first form so the binding is also done properly, I hope.

What could be the issue?

Thanks.


Solution

  • This seems to work for now regarding my basic requirement:

    View:

        class MyWizardView(SessionWizardView):
           form_list = [PatientsForm, VisitsForm]
           template_name = "main_patients.html"
    
    
           def done(self, form_list, **kargs):
              #do other processing here like saving to the database etc.
              return HttpResponse("Submitted")
    

    Template:

        {{ wizard.form.media }}
        <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
        <form action="" method="post">
          {% csrf_token %}
          {{ wizard.management_form }}
          {{ wizard.form|crispy }}
          {% if wizard.steps.prev %}
            <button class="btn btn-outline-info" name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">First</button>
            <button class="btn btn-outline-info" name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">Previous</button>
          {% endif %}
          {% if wizard.steps.step1 < wizard.steps.count %}
            <input class="btn btn-outline-info" type="submit" value="Next"/>
          {% else %}
            <input class="btn btn-outline-info" type="submit" value="Submit"/>
          {% endif %}
        </form>