Django formset - показывать дополнительные поля только тогда, когда не заданы начальные данные?
У меня есть страница с несколькими наборами форм, каждая из которых имеет префикс. Форматы создаются с использованием formset_factory
параметров по умолчанию, включая extra=1
. Строки можно добавлять или удалять с помощью JavaScript.
Если пользователь добавляет новые данные, появляется одна пустая строка. Совершенная.
Если пользователь добавил данные, но проверка формы не прошла, в этом случае набор форм заполняется данными POST с использованием MyFormset(data, prefix='o1-formsetname')
и т.д., появляются только данные, которые они ввели. Опять же, отлично. (o1
и т.д. динамически генерируются, каждый o
соответствует "опции", и каждая "опция" может иметь несколько форм).
Однако, если пользователь редактирует существующие данные, в этом случае представление заполняет набор форм с помощью MyFormset(initial=somedata, prefix='o1-formsetname')
, где somedata
- это список данных данных, которые поступают из модели в базе данных, добавляется дополнительная пустая строка после этих данных. Я не хочу, чтобы пустая строка появлялась, если пользователь явно не добавил ее с помощью JavaScript.
Есть ли какой-либо простой способ предотвратить появление набора форм в дополнительной строке, если установлены исходные данные? Причина, по которой я использую initial
в третьем примере, заключается в том, что если бы я просто передал данные при использовании MyFormset(somedata, prefix='o1-formsetname')
, мне пришлось бы сделать дополнительный шаг по переформатированию всех данных в файл стиля POSTdata, включая префиксы для каждого поля, например o1-formsetname-1-price: x
и т.д., а также вычисление данных формы управления, что добавляет всю нагрузку осложнений.
Одним из решений может быть перехват набора форм перед его отправкой в шаблон и вручную удалить строку, но атрибут extra_forms
, похоже, не доступен для записи, а установка extra
на 0
не делает никаких разница. Я также мог бы JavaScript обнаружить этот случай и удалить строку. Однако я не могу не думать о том, что мне не хватает чего-то очевидного, поскольку поведение, которое я хочу, - это то, что казалось бы разумным ожидаемым поведением для меня.
Спасибо.
Ответы
Ответ 1
Я придумал решение, которое работает с Django 1.1. Я создал подкласс BaseFormSet
, который переопределяет метод total_form_count
таким образом, что если исходные формы существуют, то сумма не включает дополнительные формы. Возможно, бит взлома, и, возможно, там лучшее решение, которое я не смог найти, но он работает.
class SensibleFormset(BaseFormSet):
def total_form_count(self):
"""Returns the total number of forms in this FormSet."""
if self.data or self.files:
return self.management_form.cleaned_data[TOTAL_FORM_COUNT]
else:
if self.initial_form_count() > 0:
total_forms = self.initial_form_count()
else:
total_forms = self.initial_form_count() + self.extra
if total_forms > self.max_num > 0:
total_forms = self.max_num
return total_forms
Ответ 2
Используйте аргумент ключевого слова max_num
для formset_factory
:
MyFormset = formset_factory([...], extra=1, max_num=1)
Подробнее см. ограничение максимального количества форм.
Одна задержка: предположительно вы хотите обрабатывать более одной пустой формы. Это не слишком сложно; просто убедитесь, что вы не используете аргумент ключевого слова max_num
на стороне обработки POST.