Как сделать форму с добавлением нескольких элементов на django?

Для создания формы с возможностью добавления нескольких элементов на Django, мы можем использовать механизм вложенных форм или динамического добавления полей с помощью JavaScript. Рассмотрим оба подхода.

1. Использование вложенных форм:
В Django мы можем использовать встроенный класс FormSet, который позволяет работать с набором форм. Чтобы создать форму с возможностью добавления нескольких элементов, вам необходимо сначала создать саму форму, а затем определить класс FormSet на основе этой формы. Здесь приведен пример кода:

   # forms.py
   from django import forms

   class MyForm(forms.Form):
       name = forms.CharField(max_length=100)
       email = forms.EmailField()

   MyFormSet = forms.formset_factory(MyForm, extra=1)  # extra - количество пустых форм, отображаемых по умолчанию

   # views.py
   from django.shortcuts import render

   def my_view(request):
       if request.method == 'POST':
           formset = MyFormSet(request.POST)
           if formset.is_valid():
               for form in formset:
                   # обработка данных формы
                   name = form.cleaned_data['name']
                   email = form.cleaned_data['email']
                   # дополнительная логика
       else:
           formset = MyFormSet()
       return render(request, 'my_template.html', {'formset': formset})

   # my_template.html
   <form method="POST">
       {% csrf_token %}
       {{ formset.management_form }}
       {% for form in formset %}
           {{ form }}
       {% endfor %}
       <input type="submit" value="Submit">
   </form>

В этом примере форма MyForm содержит поля name и email. Класс MyFormSet, созданный с помощью forms.formset_factory(), используется для визуализации и обработки набора форм. В представлении my_view мы обрабатываем отправку формы, а затем обрабатываем каждую форму из набора форм отдельно.

2. Динамическое добавление полей с использованием JavaScript:
Второй подход состоит в том, чтобы использовать JavaScript для динамического добавления полей формы. Этот подход особенно полезен, когда мы хотим, чтобы пользователь мог добавлять и удалять поля формы динамически на странице без необходимости перезагрузки страницы. Самый распространенный подход - это использование библиотеки jQuery и ее плагина django-dynamic-formset.

Подключите jQuery на страницу:

   <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

Установите django-dynamic-formset:

   pip install django-dynamic-formset

Создайте форму и представление:

   # forms.py
   from django import forms

   class MyForm(forms.Form):
       name = forms.CharField(max_length=100)
       email = forms.EmailField()

   # views.py
   from django.shortcuts import render

   def my_view(request):
       return render(request, 'my_template.html', {'form': MyForm()})

С помощью django-dynamic-formset мы можем добавить функциональность добавления и удаления полей в форму с помощью JavaScript:

   <!-- my_template.html -->
   <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

   <form method="POST">
       {% csrf_token %}
       <div class="formset">
           {{ form.management_form }}
           {% for form in formset %}
               {{ form }}
           {% endfor %}
       </div>
       <input type="button" class="add-row" value="Добавить">
       <input type="submit" value="Submit">
   </form>

   <script>
       $(document).ready(function() {
           $('.formset').formset({
               addText: 'Добавить',
               deleteText: 'Удалить',
               prefix: '{{ formset.prefix }}'
           });
       });
   </script>

В этом примере мы создаем кнопку "Добавить" и кнопку "Удалить", которые позволяют добавлять и удалять поля формы при клике. JavaScript-код связывает форму и кнопки с помощью класса .formset. При отправке формы Django будет обрабатывать данные формы, как если бы она была обычной формой.

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