Django, если TOTAL_FORMS имеет другое число, чем фактическое количество форм

При работе с динамическим набором форм существуют моменты, когда TOTAL_FORMS больше фактического числа форм. Кроме того, этот вход TOTAL_FORMS может быть легко изменен пользователем. Так, например, мой ввод

Однако отображаются только 2 фактических формы.

В этом случае Django генерирует ненужные пустые формы в переменной formset.forms. И это создает проблему, если есть ошибки проверки и снова отображается форма. Страница показывает эти нежелательные формы. (В этом примере должны отображаться только две фактические формы, но поскольку общее число равно 5, пользователь видит всего 5 форм)

Как удалить эти нежелательные формы, обновить общий счет и повторно отобразить формы с обновленным набором форм?

EDIT: Сложной частью является также обновление индексов при удалении форм. Таким образом, общее число совпадений совпадает с индексом последней формы.

1 ответ

Это старый вопрос, и я не уверен, изменился ли Django с тех пор. Но так, как я это делал, это написать функцию для обновления данных набора форм. Ключ здесь - сначала сделать копию данных набора форм (QueryDict). Вот код:

def updateFormDataPrefixes(formset):
 """
 Update the data of the formset to fix the indices. This will assign
 indices to start from 0 to the length. To do this requires copying 
 the existing data and update the keys of the QueryDict. 
 """
 # Copy the current data first
 data = formset.data.copy()
 i = 0
 nums = []
 for form in formset.forms:
 num = form.prefix.split('-')[-1]
 nums.append(num)
 # Find the keys for this form
 matched_keys = [key for key in data if key.startswith(form.prefix)]
 for key in matched_keys:
 new_key = key.replace(num, '%d'%i)
 # If same key just move to the next form
 if new_key == key:
 break
 # Update the form key with the proper index
 data[new_key] = data[key]
 # Remove data with old key
 del data[key]
 # Update form data with the new key for this form
 form.data = data
 form.prefix = form.prefix.replace(num, '%d'%i)
 i += 1
 total_forms_key = formset.add_prefix(TOTAL_FORM_COUNT)
 data[total_forms_key] = len(formset.forms)
 formset.data = data

licensed under cc by-sa 3.0 with attribution.