Возможно ли предварительно заполнить Django FormSets полями FileFields?
Спасибо, что нашли время прочитать мой вопрос. Вот моя проблема. Я создаю вложения на форме. Множественные. Все хорошо и отлично. Вот в чем проблема... Я хочу "ПОЛУЧИТЬ" эти вложения на форме обновления, чтобы они отображались и могли быть удалены, если форма будет одобрена. Это оказывается сложной задачей. В некоторых случаях я заполняю формы, используя словарь для получения данных, которые мне нужны в качестве исходных данных. Все работает как ожидалось, за исключением FileFields или FieldFile, как его называет Django. Я прочитал несколько подобных статей на SO... но ничего не помогает. Я понимаю проблемы безопасности и не пытаюсь "ЗАСТАВИТЬ" загружать данные... Я просто хочу получить имя вложения и скопировать его в другую модель. Моя форма отправляется, но вложения не обрабатываются.
Здесь мой код....
HTML...
<form method="POST" enctype="multipart/form-data" id="forms">
{{ procedure_attachment_form.management_form }}
{{ procedure_attachment_form.non_form_errors }}
{% for fileform in procedure_attachment_form.forms %}
{{ fileform.id }}
<div class="inline {{ procedure_attachment_form.prefix }}">
{{ fileform.attachments }}
{% if procedure_attachment_form.non_form_errors %}
<h3 class="spacer174">
{{ procedure_attachment_form.non_form_errors }}
</h3>
{% endif %}
{% if fileform.attachments.errors %}
<h3 class="spacer174">
{{ fileform.attachments.errors }}
</h3>
{% endif %}
{{ fileform.procedure.as_hidden }}
</div>
{% endfor %}
МОЯ ФОРМА...
class UpdateProcedureFilesForm(forms.ModelForm):
class Meta:
model = UpdateProcedureFiles
fields = ['attachments']
widgets = {
'attachments': ClearableFileInput(attrs={'multiple': True}),
}
Мой вид (CreateView )
Опять же, все работает. Единственное исключение - когда задействованы FileFields...тогда ничего не получается. Заранее спасибо за любые мысли.
Любезный джентльмен из группы Facebook по имени Мэтт Хоскинс предоставил мне это объяснение, и после трех дней исследований я склонен ему верить. Заканчиваю с основной предпосылкой, что это непросто возможно, если возможно вообще. Переходим к другому подходу. Вот его более красноречивое резюме....Ах, я думаю, я понимаю проблему. Это не проблема с наборами форм вообще, как это бывает - ключ в том, что вы пытаетесь установить начальное значение для поля файла на форме, которая не привязана к экземпляру. Файловые входы HTML не могут принимать начальное значение (это не особенность django, просто так работает HTML/браузеры), поэтому когда django отображает виджет файлового поля, начального значения никогда не будет, даже если у базовых данных оно есть. Работа django с редактированием экземпляров модели с файловыми полями заключается в том, что если пользователь выбирает файл в форме и отправляет, то браузер отправляет этот файл в качестве значения для поля, и django обновляет поле в экземпляре, однако если пользователь не выбирает файл в форме, то браузер не отправляет это поле вообще (не то чтобы он отправляет пустое значение для поля, просто не будет записи для поля в request. FILES), и когда это произойдет, django не будет обновлять поле на экземпляре (т.е. оно сохранит свое существующее значение). Виджет ClearableFileInput добавляет к обычному HTML вводу файла дополнительное поле HTML checkbox, чтобы позволить очистить существующее значение, которое будет запрошено, и отобразит имя любого существующего значения, но сам ввод файла по-прежнему не может иметь никакого начального значения, сохраненного в нем. Поэтому, когда пользователь отправляет форму с виджетом ClearableFileInput без выбора нового файла, то в request.FILES ничего не появляется для этого поля (значение связанного с ним поля clear checkbox будет передано, но это только говорит django, очищать ли поле файла в данном экземпляре). Так что если бы ваш набор инлайн-форм был предварительно заполнен фактическими экземплярами, а не только начальными, то это бы работало, но поскольку вы пытаетесь создать новый набор экземпляров на основе существующих данных, и эти существующие данные передаются только HTML-формой, и поскольку html-поля ввода файлов не могут иметь начального значения, то в итоге вы не получаете ничего для полей, к которым пользователь не прикасается (тот факт, что вы можете видеть значения файлов, отображаемые виджетами ClearableFileInput, подхватывающими их из initial, вводит в заблуждение - эти значения не передаются формой). Надеюсь, это имеет смысл... Скоро напишу еще несколько размышлений 🙂