jazzband / django-formtools

A set of high-level abstractions for Django forms
https://django-formtools.readthedocs.io
BSD 3-Clause "New" or "Revised" License
797 stars 135 forks source link

SessionWizard not saving data between form steps #147

Open motatoes opened 5 years ago

motatoes commented 5 years ago

I asked this question on stackoverflow. My question is about saving information between fields.

I am trying to create a multi-step form wizard using django-formtools. I have a main model called Report and several ModelForms as follows:


class ReportFormP1(forms.ModelForm):
    class Meta:
        model = Report
        fields = [
            'company',
            'address_line_1',
            'address_line_2',
            'responsible_person',
            'person_consulted',
            'assessor_name',
            'previous_assessment_date',
            'review_date',
        ]

# section 1
class ReportFormP2(forms.ModelForm):
    class Meta:
        model = Report
        fields = [
            "premise_num_floors",
            "premise_floor_area",
            "premise_occupancy",
            "premise_occupancy_comments",
        ]

in my views, I have created the following view:

class ReportWizardView(SessionWizardView):
    template_name = 'reporting/report_create2.html'
    form_list = [ReportFormP1, ReportFormP2]

    def done(self, form_list, **kwargs):
        return render(self.request, 'done.html', {
            'form_data': [form.cleaned_data for form in form_list],
        })

And my relevant template looks as follows:

{% extends '_base.html' %}
{% load static %}
{% load i18n %}
{% load crispy_forms_tags %}

<!-- templates/home.html -->
{% load socialaccount %}

{% block title %}Create a report{% endblock title %}

{% block extra_css %}
    {{ wizard.form.media }}
{% endblock extra_css %}

{% block content %}
<div class="container">
    <h1>Create a report</h1>

    <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>

    <form action="" method="post">
        {% csrf_token %}
        {{ wizard.management_form }}

        {% if wizard.form.forms %}
            {{ wizard.form.management_form }}
            {% for form in wizard.form.forms %}
                {{ form|crispy }}
            {% endfor %}
        {% else %}
            {{ wizard.form|crispy }}
        {% endif %}

        <div class="text-center">
            {% if wizard.steps.prev %}
            <button class="btn btn-lg btn-warning" name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}" formnovalidate>{% trans "first step" %}</button>
            <button class="btn btn-lg btn-primary" name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}" formnovalidate>{% trans "prev step" %}</button>
            {% endif %}
            {% if wizard.steps.next %}
                <button class="btn  btn-lg btn-primary" name="wizard_goto_step" type="submit" value="{{ wizard.steps.next }}">{% trans "next step" %}</button>
            {% endif %}

            <input class="btn btn-lg btn-success" type="submit" name="Submit" value="Create report">

        </div>

    </form>

    <hr>
    <hr>

</div>

{% endblock content %}

My urls.py look as follows:

    path('create_report2', ReportWizardView.as_view(), name="report_create2"),

My problem is that the form steps are not being saved when I click on next, and then previous (the form is valid). Bellow is an example

First form loaded:

8e66r.png

After clicking on 'next':

8eQnO.png

Now when i click on 'previous', everything is gone:

8eMqq.png

I wonder what I have missed?

BongzMD commented 4 years ago

Hi Motatoes, did you get assistance with this problem? I am struggling with the same issue.

motatoes commented 4 years ago

@BongzMD I did not get an answer regarding formtools and I don't remember if I found out what was wrong so I created my own wizard view

I made all the fields in my table nullable. I have a create report view which included:


class CreateReportView(LoginRequiredMixin,
                       ReportPermissionMixin,
                       RedirectView):
    def get_redirect_url(self, *args, **kwargs):
        # creating a draft report
        self.report_add_permission(self.request)
        report = Report.objects.create(user=self.request.user)
        return reverse('reporting:report_update', kwargs={"pk": report.id})

I also copied bits of the SesssionWizard for my UpdateReportView but instead of using a session I save the form records directly in the table at every step (provided the form is valid)

BongzMD commented 4 years ago

Okay thanks

On Sun, 3 May 2020, 12:52 Mohamed, notifications@github.com wrote:

@BongzMD https://github.com/BongzMD I did not get an answer regarding formtools and I don't remember if I found out what was wrong so I created my own wizard view

I made all the fields in my table nullable. I have a create report view which included:

class CreateReportView(LoginRequiredMixin, ReportPermissionMixin, RedirectView): def get_redirect_url(self, *args, **kwargs):

creating a draft report

    self.report_add_permission(self.request)
    report = Report.objects.create(user=self.request.user)
    return reverse('reporting:report_update', kwargs={"pk": report.id})

I also copied bits of the SesssionWizard for my UpdateReportView but instead of using a session I save the form records directly in the table at every step (provided the form is valid)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/jazzband/django-formtools/issues/147#issuecomment-623090882, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOLJUSH7HJQXKPEEOO7X7H3RPVEHBANCNFSM4IMMV3JQ .

stephappiah commented 4 years ago

From your template, the "next" button only takes you to the next page but doesn't actually 'save' the data. you can fix that by using an input field instead on the next button as seen below.

<input type="submit" value="{% trans "Next" %}"/>

elmcrest commented 4 years ago

Isn't there a way to save data in the session and reuse it in the steps? directly saving to DB seems a little wrong to me tbh... Btw, the behaviour is the same for me for SessionWizardView or CookieWizardView

Samoht1 commented 2 years ago

I also have this issue

From your template, the "next" button only takes you to the next page but doesn't actually 'save' the data. you can fix that by using an input field instead on the next button as seen below.

<input type="submit" value="{% trans "Next" %}"/>

When trying @stephappiah's I get a SuspiciousOperation error saying "ManagementForm data is missing or has been tampered."

EDIT: Apparently I misspelled wizard.management_form