Django - Как добавить несколько форм в зависимости от вводимого числа

У меня есть поле ввода, где клиент добавляет номер для покупки членства, затем получает формы в соответствии с номерами 1,2 или 5, затем показывает 1,2 или 5 форм с полями ввода, в которые будут добавлены данные.

Например:

  1. customer will come to the site and click on buy membership

  2. the first page will How many Memberships do you want to buy? ==> input Field in which will add 1,2, or 5

  3. based on how many members enter a show a page to collect information of members

Я достиг добавления нескольких форм пользователем с помощью кнопки. Но я хочу, чтобы на первой странице пользователь ввел количество форм, которое он хочет, а затем в соответствии с его количеством я создам для него нужное количество форм.

О том, как я работал с Django formsets, вы можете увидеть мой код

models.py

from django.db import models

class MemberShip(models.Model):
    GENDER = (
            ('Male', 'Male'),
            ('Female', 'Female'),
            )
    EXPERIENCE = (
            ('First Time', 'First Time'),
            ('Have skier and snowboard before', 'Have skier and snowboard before'),
            )
    first_name = models.CharField(max_length=200, null=True)
    last_name = models.CharField(max_length=200, null=True)
    experience = models.CharField(max_length=100, null=True, choices=EXPERIENCE)
    date_birth = models.CharField(max_length=20, null=True)
    gender = models.CharField(max_length=20, null=True, choices=GENDER)
    phone = models.CharField(max_length=20, null=True)
    
    def __str__(self):
      return self.first_name

forms.py

from django.forms import modelformset_factory
from .models import MemberShip


MemberShipFormSet = modelformset_factory(
    MemberShip, fields=("first_name", "last_name", "experience", "date_birth", "gender", "phone"), extra=1
)

View.py

from django.views.generic import ListView, TemplateView
from .forms import MemberShipFormSet
from .models import MemberShip
from django.urls import reverse_lazy

class MemberShipList(ListView):
    model = MemberShip
    template_name = "customer/memberships_list.html"

class MemberShipAdd(TemplateView):
    template_name = "customer/memberships_add.html"

    def get(self, *args, **kwargs):
        formset = MemberShipFormSet(queryset=MemberShip.objects.none())
        return self.render_to_response({'membership_formset': formset})

    # Define method to handle POST request
    def post(self, *args, **kwargs):

        formset = MemberShipFormSet(data=self.request.POST)

        # Check if submitted forms are valid
        if formset.is_valid():
            formset.save()
            return redirect(reverse_lazy("member_ships_list"))

        return self.render_to_response({'membership_formset': formset})

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Add MemberShip</title>
</head>
<body>
    <h1>Add a new MemberShip</h1>
    <form id="form-container" method="POST">
        {% csrf_token %}
        {{membership_formset.management_form}}
        {% for form in membership_formset %}
            <div class="membership-form">
                {{form.as_p}}
                <hr>
            </div>
        {% endfor %}
        <button id="add-form" type="button">Add Another MemberShip</button>
        <button type="submit">Create MemberShips</button>        
    </form>
    </body>

    <script>
        let membershipForm = document.querySelectorAll(".membership-form")
        let container = document.querySelector("#form-container")
        let addButton = document.querySelector("#add-form")
        let totalForms = document.querySelector("#id_form-TOTAL_FORMS")

        let formNum = membershipForm.length-1
        addButton.addEventListener('click', addForm)

        function addForm(e){
            e.preventDefault()

            let newForm = membershipForm[0].cloneNode(true)
            let formRegex = RegExp(`form-(\\d){1}-`,'g')

            formNum++
            newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`)
            container.insertBefore(newForm, addButton)
            
            totalForms.setAttribute('value', `${formNum+1}`)
        }
    </script>
</html>

Заранее спасибо

Несмотря на (обоснованные) опасения по поводу UX, высказанные другими пользователями, вы можете добиться требуемого рабочего процесса, используя две страницы и добавив параметр в url для второй страницы. Например:

path("new-membership/", . . .),
path("new-membership/<int:num_members>/", . . .),

Тогда ваша страница нового членства может просто использовать форму для перенаправления на страницу второго этапа с нужным количеством членств в url. Вам даже не нужно использовать форму на первой странице, поскольку вы никак не изменяете базу данных.

Вернуться на верх