Функция formset_factory

Функция formset_factory применяется для создания набора форм (formset), который представляет собой коллекцию однотипных форм. Она принимает базовую форму и возвращает класс FormSet, позволяющий управлять несколькими экземплярами этой формы одновременно. Аргументы передаются в виде ключевых параметров, где основным является форма, а дополнительные параметры управляют количеством форм, валидацией и другими аспектами работы набора.

Синтаксис

pythonfrom django.forms import formset_factory

FormSetClass = formset_factory(form, **options)

Основные параметры

Функция принимает следующие параметры:

Пример . Базовое использование

Создадим простую форму для ввода данных о книге и набор форм для добавления нескольких книг:

pythonfrom django import forms
from django.forms import formset_factory

class BookForm(forms.Form):
  title = forms.CharField(max_length=100, label="Название")
  author = forms.CharField(max_length=50, label="Автор")
  year = forms.IntegerField(label="Год издания")

BookFormSet = formset_factory(BookForm, extra=3)

formset = BookFormSet()
for form in formset:
  print(form.as_p())

Результат выполнения кода:

python"<p><label for="id_form-0-title">Название:</label> <input type="text" name="form-0-title" maxlength="100" id="id_form-0-title"></p>
<p><label for="id_form-0-author">Автор:</label> <input type="text" name="form-0-author" maxlength="50" id="id_form-0-author"></p>
<p><label for="id_form-0-year">Год издания:</label> <input type="number" name="form-0-year" id="id_form-0-year"></p>
... (всего 3 формы)"

Пример . С обработкой данных

Рассмотрим пример обработки данных из набора форм, отправленных методом POST:

pythonfrom django import forms
from django.forms import formset_factory
from django.shortcuts import render

class BookForm(forms.Form):
  title = forms.CharField(max_length=100)
  author = forms.CharField(max_length=50)
  year = forms.IntegerField()

def add_books(request):
  BookFormSet = formset_factory(BookForm, extra=2)

  if request.method == 'POST':
    formset = BookFormSet(request.POST)

    if formset.is_valid():
      for form in formset:
        if form.cleaned_data:
          title = form.cleaned_data['title']
          author = form.cleaned_data['author']
          year = form.cleaned_data['year']
          print(f"Book: {title} by {author} ({year})")

  else:
    formset = BookFormSet()

  return render(request, 'books.html', {'formset': formset})

Пример . С ограничением количества форм

Используем параметры max_num и min_num для ограничения количества форм:

pythonfrom django import forms
from django.forms import formset_factory

class BookForm(forms.Form):
  title = forms.CharField(max_length=100)
  author = forms.CharField(max_length=50)

BookFormSet = formset_factory(
  BookForm,
  extra=2,
  min_num=1,
  max_num=5,
  validate_min=True,
  validate_max=True
)

formset = BookFormSet()
print(f"Total forms: {formset.total_form_count()}")
print(f"Initial forms: {formset.initial_form_count()}")

Результат выполнения кода:

python"Total forms: 3"
"Initial forms: 1"

Пример . С удалением форм

Включим возможность удалять формы из набора с помощью параметра can_delete:

pythonfrom django import forms
from django.forms import formset_factory

class BookForm(forms.Form):
  title = forms.CharField(max_length=100)
  author = forms.CharField(max_length=50)

BookFormSet = formset_factory(
  BookForm,
  extra=2,
  can_delete=True
)

formset = BookFormSet()
for form in formset:
  if form.can_delete:
    print("Form has delete checkbox")

Пример . С изменением порядка форм

Используем параметр can_order для управления порядком форм:

pythonfrom django import forms
from django.forms import formset_factory

class BookForm(forms.Form):
  title = forms.CharField(max_length=100)
  author = forms.CharField(max_length=50)

BookFormSet = formset_factory(
  BookForm,
  extra=3,
  can_order=True
)

formset = BookFormSet()
for i, form in enumerate(formset):
  order_field = form.fields.get('ORDER')
  if order_field:
    print(f"Form {i} has ORDER field")

Смотрите также

  • класс Form,
    который используется для создания базовых форм
  • функция modelformset_factory,
    которая создаёт набор форм на основе модели
  • функция inlineformset_factory,
    которая создаёт набор форм для связанных моделей
  • метод is_valid,
    который проверяет валидность формы