Как передать файлы, которые были загружены через модальную форму начальной загрузки в django form / formset? - PullRequest
0 голосов
/ 05 апреля 2019

Я создаю страницу для размещения нового заказа, которая может состоять из нескольких элементов. Новый элемент добавляется через модальную форму начальной загрузки, и одно из полей является входом для загрузки файла (это 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 %}

Ценю любые идеи, как решить эту проблему.

...