AndrewIngram / django-extra-views

Django's class-based generic views are awesome, let's have more of them.
MIT License
1.39k stars 172 forks source link

Saving multiple instances of form with CreateWithInlineViews and InlineFormSetFactory #212

Closed algoth closed 4 years ago

algoth commented 4 years ago

I am trying to do something similar to what this article mentions by using vuejs. https://www.codementor.io/@ankurrathore/handling-multiple-instances-of-django-forms-in-templates-8guz5s0pc

Basically allowing a user to create multiple categories in a survey form by clicking on an add new category button.

But only last form values are getting saved. I want to save all the categories added by the user (just like django admin default behaviour).

This is how the files look:

views.py

class QuestionInline(InlineFormSetFactory):
    fields = ['text', 'order', 'required', 'type', 'choices', 'category']
    model = OIQuestion
    factory_kwargs = {'extra': 1,'can_delete': True, 'max_num':None}

class CategoryInline(InlineFormSetFactory):
    fields = ['name', 'order', 'description']
    model = OICategory
    factory_kwargs = {'extra': 1,'can_delete': True, 'max_num':None}

class OISurveyCreateView(NamedFormsetsMixin, CreateWithInlinesView):
    fields = ['name', 'description', 'is_published', 'need_logged_user', 'display_by_question']
    model = OISurvey
    inlines = [CategoryInline, QuestionInline]
    inlines_names = ['categories', 'questions']
    # template_name = "TEMPLATE_NAME"

survey_form.html

{% extends 'base.html' %}

{% load bootstrap4 %}
{% block body %}

<div id="app" class="container">
    <h2>Create a New Survey</h2>
    <form action="{% url 'oisurveys:survey-create' %}" method="post">
        {% csrf_token %}
        {% bootstrap_form form %}
        <h3>Categories</h3>
            {{ categories.management_form }}
            {% for form in categories %}
            <div v-for="(line,index) in lines" v-bind:key="index" class="row col-10">         
                    {{ form }}
                    <div class="float-right block">
                        <span @click="deleteLine(index)" class="btn btn-danger">Remove category</span>
                    </div>               
            </div>
            {% endfor %}

        <div class="float-right block">
            <span @click="addLine" class="btn btn-primary">Add a category</span>
        </div>    
        <h3>Questions</h3>
        {{ questions.management_form }}
        {% for form in questions %}
                    {{ form }}
        {% endfor %}

        <br>
        <input type="submit" value="Submit" class="btn btn-primary btn-lg">
    </form>
</div>

<script>
  new Vue({
      el: '#app',
      data () {
        return {
          lines: [],
        }
    },

    methods: {
    addLine () {
        this.lines.push('new-line')
        },

    deleteLine(lineId) {
        this.lines.splice(lineId, 1)
    }
    },
    mounted () {
    this.addLine()
    }
});
</script>
{% endblock body %}
a-wip0 commented 3 years ago

did you found the answer?