Django - Как добавить несколько форм в зависимости от вводимого числа
У меня есть поле ввода, где клиент добавляет номер для покупки членства, затем получает формы в соответствии с номерами 1,2 или 5, затем показывает 1,2 или 5 форм с полями ввода, в которые будут добавлены данные.
Например:
customer will come to the site and click on buy membership
the first page will How many Memberships do you want to buy? ==> input Field in which will add 1,2, or 5
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. Вам даже не нужно использовать форму на первой странице, поскольку вы никак не изменяете базу данных.