РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
407 of 818 menu

Функция modelformset_factory

Функция modelformset_factory применяется для динамического создания класса набора форм, связанного с моделью Django. Она принимает модель и набор параметров, возвращая класс BaseModelFormSet. Полученный набор форм позволяет обрабатывать несколько экземпляров модели в одной форме, что удобно для массового редактирования, добавления или удаления записей. В отличие от обычных форм, где работа идет с одной записью, набор форм дает возможность изменять сразу несколько объектов.

Основные параметры функции:

  • model - модель Django, на основе которой создаются формы;
  • fields - список полей модели, которые будут включены в формы;
  • exclude - список полей, которые нужно исключить из форм;
  • extra - количество дополнительных пустых форм для добавления новых записей (по умолчанию 1);
  • max_num - максимальное количество форм в наборе;
  • min_num - минимальное количество форм в наборе;
  • validate_max - флаг, определяющий, нужно ли проверять максимальное количество форм;
  • validate_min - флаг, определяющий, нужно ли проверять минимальное количество форм;
  • form - пользовательский класс формы (по умолчанию ModelForm);
  • formset - пользовательский класс набора форм (по умолчанию BaseModelFormSet);
  • widgets - словарь виджетов для полей формы;
  • localized_fields - список полей, которые должны быть локализованы;
  • labels - словарь для переопределения меток полей;
  • help_texts - словарь для переопределения подсказок полей;
  • error_messages - словарь для переопределения сообщений об ошибках;
  • can_delete - флаг, добавляющий флажок для удаления объектов.

Все параметры передаются в виде именованных аргументов, при этом обязательными являются только model и хотя бы один из параметров fields или exclude.

Синтаксис

from django.forms import modelformset_factory ModelFormSet = modelformset_factory( model, fields='__all__', extra=1, max_num=None, min_num=None, can_delete=False )

Пример

Допустим, у нас есть модель Article для статей. Создадим набор форм для редактирования заголовков и статусов статей:

from django.db import models class Article(models.Model): title = models.CharField(max_length=200) status = models.CharField(max_length=20) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.title

Создадим набор форм и выведем формы для всех существующих статей:

from django.forms import modelformset_factory from myapp.models import Article ArticleFormSet = modelformset_factory( model=Article, fields=['title', 'status'] ) queryset = Article.objects.all() formset = ArticleFormSet(queryset=queryset) for form in formset: print(form.instance.title, form.instance.status)

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

"article 1 published" "article 2 draft" "article 3 published"

Пример

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

from django.forms import modelformset_factory from myapp.models import Article ArticleFormSet = modelformset_factory( model=Article, fields=['title', 'status'], extra=2, can_delete=True, max_num=10 ) queryset = Article.objects.filter(status='draft') formset = ArticleFormSet(queryset=queryset) if formset.is_valid(): instances = formset.save() print(f"Saved {len(instances)} articles") else: print("Formset is not valid")

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

"Saved 2 articles"

Пример

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

from django import forms from django.forms import modelformset_factory from myapp.models import Article class CustomArticleForm(forms.ModelForm): class Meta: model = Article fields = ['title', 'status'] def clean_title(self): title = self.cleaned_data.get('title') if len(title) < 3: raise forms.ValidationError("Title is too short") return title class CustomArticleFormSet(forms.BaseModelFormSet): def clean(self): super().clean() titles = [] for form in self.forms: if form.cleaned_data and 'title' in form.cleaned_data: title = form.cleaned_data['title'] if title in titles: raise forms.ValidationError( "Duplicate titles are not allowed" ) titles.append(title) ArticleFormSet = modelformset_factory( model=Article, form=CustomArticleForm, formset=CustomArticleFormSet, extra=1, can_delete=True ) queryset = Article.objects.all() formset = ArticleFormSet(queryset=queryset) if formset.is_valid(): formset.save() print("All articles saved successfully") else: print("Formset errors:", formset.errors)

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

"All articles saved successfully"

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

  • функция formset_factory,
    которая создает набор форм на основе обычной формы
  • функция inlineformset_factory,
    которая создает набор форм для работы с внешними ключами
  • класс ModelForm,
    который используется для создания форм на основе моделей
  • метод save,
    который сохраняет данные формы в базу данных
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить