Я создаю страницу для размещения нового заказа, которая может состоять из нескольких элементов. Новый элемент добавляется через модальную форму начальной загрузки, и одно из полей является входом для загрузки файла (это ImageField в модели django). Моя проблема в том, что я не знаю, как и где хранить эти загруженные файлы, чтобы я мог сохранить их все сразу при отправке основной формы заказа.
Есть две модели, с которыми я работаю: Order и Item, и они связаны отношением «один ко многим» (например, Item.order_id - это FK для Order.id). Таким образом, пользователь открывает страницу для нового заказа, заполняет все поля заказа, затем добавляет несколько элементов (с изображениями), нажимает кнопку Отправить, а затем заказ и элементы сохраняются в БД.
Там также должен быть красивый и компактный список добавленных элементов, который обновляется после добавления каждого нового элемента, поэтому у меня есть таблица начальной загрузки, которая просто обновляется с помощью js-скрипта.
Сначала я решил сохранить все отправленные значения в этой таблице (в скрытых полях), но не мог понять, как сохранить загруженный файл, и, честно говоря, это не выглядит хорошей идеей.
Мое второе решение состояло в том, чтобы использовать невидимый набор форм django (с display: none), передавать все данные туда, а затем просто обрабатывать их как обычный набор форм, заполненный пользователем. Я также не считаю это красивым, но этот подход работал - пока он не пришел к загруженным файлам. HTMLInputElement не позволяет устанавливать какие-либо значения (кроме '') программно, поэтому я не могу ничего передать из моей модальной формы.
И вот где я застрял. Какова лучшая практика для этой ситуации?
AJAX? Отправлять загруженные файлы на сервер и временно хранить их там? Но тогда мне также придется чистить файлы для неподтвержденных заказов. Может быть, есть другой способ?
models.py
class Order(models.Model):
order_date = models.DateTimeField(null=False)
customer = models.ForeignKey('customers.Customer', models.SET_NULL, blank=False, null=False)
comment = models.CharField(max_length=255, blank=True, null=True)
class Item(models.Model):
name = models.CharField(max_length=255)
link = models.CharField(max_length=255, null=True)
img = models.ImageField(upload_to='uploads/%Y/%m/%d/', blank=True, null=True)
comment = models.CharField(max_length=255, blank=True, null=True)
forms.py
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ('order_date',
'customer',
'comment'
)
ItemFormSet = forms.inlineformset_factory(Order, Item, can_delete=False, extra=0,
fields=('name',
'link',
'img',
'comment')
)
template.html
Проблема на самом деле здесь, в блоке скриптов:
{% extends 'base.html' %}
{% block content %}
<!-- Modal form -->
<div class="modal fade" tabindex="-1" role="dialog" id="modal">
<div class="modal-dialog" role="document">
<div class="modal-content"></div>
{% csrf_token %}
</div>
</div>
<!-- Empty form for a formset -->
<div id="empty_form" style="display:none">
<div class='no_error'>
{{ items_form_set.empty_form.as_p }}
</div>
</div>
<!-- Main form -->
<form id="add_order_form" method="post" enctype="multipart/form-data">
<!-- Order form -->
<div>
{% csrf_token %}
{{ order_form.as_p }}
</div>
<!-- List of added items -->
<div>
<table class="table" id="items_table">
</table>
</div>
<!-- Invisible formset with Items-->
<div id="form_set" style="display:none">
{{ items_form_set.management_form }}
{% for form in items_form_set.forms %}
<div class="no_error">
{{ form.as_p }}
</div>
{% endfor %}
</div>
</form>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
// Add item button
$("#add_item").modalForm({formURL: "{% url 'orders:add_new_item' %}"});
// Submitting the New Item form
$(document).ready(function () {
$('#modal').on('submit', function(event) {
event.preventDefault();
// Collect data from modal form
var data = {Name: $('input:text[name=name]').val(),
Link: $('input:text[name=link]').val(),
Comment: $('input:text[name=comment]').val(),
Img: $('input[type=file][name=img]').val()
};
// Append an empty form to a formset
var form_idx = $('#id_items_form_set-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_items_form_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
// Fill the appended form
var form_prefix = 'id_items_form_set-' + form_idx.toString();
$('#' + form_prefix + '-name').val(data['Name']);
$('#' + form_prefix + '-link').val(data['Link']);
$('#' + form_prefix + '-comment').val(data['Comment']);
// -----------------------
// This is what I want but can't do:
// -----------------------
// $('#' + form_prefix + '-img').val(data['Img']);
$('#modal').modal('hide');
$('#modal :input').val('');
$('#modal select').val('');
});
</script>
{% endblock %}
Ценю любые идеи, как решить эту проблему.