elo80ka / django-dynamic-formset

A jQuery plugin that allows you dynamically add new forms to a rendered django formset.
677 stars 311 forks source link

Dynamic Formsets with Django Formtools #170

Closed jameskomo closed 4 years ago

jameskomo commented 4 years ago

I have been trying to integrate Dynamic formsets with Django form tools but I am stuck. When I do a normal form wizard I am able to complete the entire process but when I try introduce Dynamic formsets in one of the templates I get CSRF errors. I have a form in the wizard that I would like users to be able to add questions dynamically. The form is a model form. My template looks as below:

`{% block content %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post" enctype="multipart/form-data" id="job-question">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
    {{ wizard.form.management_form }}
    {% for form in wizard.form.forms %}
        {{ form }}
        <input type="submit" value="{% trans "submit" %}"/>
    {% endfor %}
{% else %}
    {{ wizard.form }}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>

</form>

<script type="text/javascript" src="{% static 'js/jquery-min.3.4.1..js' %}"></script>
<script type="text/javascript" src="{% static 'js/jquery.formset.js' %}"></script>
<script type="text/javascript">
    $(function() {
        $('#job-question').formset();
    })
</script>
{% endblock %}`

And my formtools wizard view is as below:

`# WIZARD View Subclass for Job Forms in Forms.py
FORMS = [("0", jobs.forms.JobForm7),
         ("1", jobs.forms.JobForm1),
         ("2", jobs.forms.JobForm2),
         ("3", jobs.forms.JobForm3),
         ("4", jobs.forms.JobForm4),
         ("5", jobs.forms.JobForm5),
         ("6", jobs.forms.JobForm6),]
TEMPLATES = {"0": "jobs/job-question-create.html",
             "1": "jobs/jobforms.html",
             "2": "jobs/jobforms.html",
             "3": "jobs/jobforms.html",
             "4": "jobs/jobforms.html",
             "5": "jobs/jobforms.html",
             "6": "jobs/jobforms.html",
             }

# WIZARD View Subclass for Job Forms in Forms.py

class JobWizard(SessionWizardView):
    form_list=[JobForm7FormSet,JobForm1,JobForm2,JobForm3, JobForm4,JobForm5,JobForm6 ]
    file_storage= FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'jobs'))
    template_name="jobs/jobforms.html"

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]] 
    def done(self, form_list, form_dict, **kwargs):
        form_dict = self.get_all_cleaned_data()
        categories = form_dict.pop('categories')
        sub_categories = form_dict.pop('sub_categories')
        job_question = form_dict.pop('job_question')
        print(job_question)
        print("_________________________")
        job=Job.objects.create(**form_dict)
        job.categories=categories
        job.job_question=job_question     
        for sub_category in sub_categories:
            job.sub_categories.add(sub_category)
        # for question in job_question:
        #     job.job_question.add(question)
        job.save()   
        return redirect('job_list')
`

My Model Form handling the questions is as below:

`class JobForm7(forms.ModelForm):

    class Meta:
        model = Job
        fields = ['job_question']

JobForm7FormSet = modelformset_factory(Job, extra=1, form=JobForm7) 
`

I am getting CSRF issues with each added form having a submit button when passing the model form to the form_list but having key errors if I pass the formset to the form_lsit