Как мне сделать, чтобы моя форма Django сохраняла изображения? - PullRequest
2 голосов
/ 20 октября 2019

Я создал форму загрузки для пользователей, позволяющую им создавать объект модели. Все остальное работает, но поле изображения не хранит загруженные изображения. Я использую Crispy FormHelper в views.py, но исходный код HTML показывает, что элементы (enctype, layout_class, field_class etc...) не загружаются. Я думаю, что здесь проблема.

Вот как выглядит визуализированная форма:

enter image description here

Для контекста форма должна выглядеть следующим образом:

enter image description here

<form  class="form-horizontal" method="post" >
...
</form>

Я прошел через код и учебник Я использовал построчно, но я не могу найти, где проблемавранье.

views.py

class CarCreate(generic.CreateView):

    model = Car

    slug_field = 'id'
    slug_url_kwarg = 'car_create'

    template_name = 'showroom/car_create.html'
    form_class = CreateCarForm
    success_url = None

    def get_context_data(self, **kwargs):
        data = super(CarCreate, self).get_context_data(**kwargs)
    self.request.POST:
            data['images'] = CarImageFormSet(self.request.POST, 
        self.request.FILES)
        else:
            data['images'] = CarImageFormSet()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        images = context['images']
        with transaction.atomic():
            form.instance.seller = self.request.user
            self.object = form.save()
            if images.is_valid():
                images.instance = self.object
                images.save()
        return super(CarCreate, self).form_valid(form)

    def get_success_url(self):
        # return reverse_lazy('showroom:cars', kwargs={'slug': self.object.id}) # Throws an error
        return reverse_lazy('showroom:cars')

forms.py

class CreateCarForm(ModelForm):

    class Meta:
        model = Car
        exclude = ['seller', 'id']

    def __init__(self, *args, **kwargs):
        super(CreateCarForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = True
        self.helper.form_class = 'form-horizontal'
        self.helper.form_enctype = 'multipart/'
        self.helper.label_class = 'col-md-3 create-label'
        self.helper.field_class = 'col-md-9'
        self.helper.form_enctype = 'multipart/form-data'
        self.helper.layout = Layout(
            Div(
                ...
                Fieldset('Add Images',
                    Formset('images')),
                HTML("<br>"),
                ButtonHolder(Submit('submit', 'Save')),    
            )
        )

formset.html

{% load crispy_forms_tags %}

<table>
{{ formset.management_form|crispy }}

    {% for form in formset.forms %}
            <tr class="{% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
                {% for field in form.visible_fields %}
                <td>
                    {# Include the hidden fields in the form #}
                    {% if forloop.first %}
                        {% for hidden in form.hidden_fields %}
                            {{ hidden }}
                        {% endfor %}
                    {% endif %}
                    {{ field.errors.as_ul }}
                    {{ field }}
                </td>
                {% endfor %}
            </tr>
    {% endfor %}

</table>
</br>

{% block scripts %}
{% load static %}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>    
    <script src="{% static 'js/django-dynamic-formset/jquery.formset.js' %}"></script>
    <script type="text/javascript">
        $('.formset_row-{{ formset.prefix }}').formset({
            addText: 'add another',
            deleteText: 'remove',
            prefix: '{{ formset.prefix }}',
        });
    </script>


{% endblock %}

car_create.html

{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="container">
    <div class="card">
        <div class="card-header">
            <h2>Submit a car</h2>
        </div>
        {% csrf_token %}
        <div class="card-body">
            {% crispy form %}
        </div>
      </div>
</div>
{% endblock content %}

Обновление

Я возился с car_create.html, иХрустящая форма работает. Он по-прежнему не отображает поля FormHelper, поэтому изображения не сохраняются.

Просматривая визуализированный код формы, он отображает form-horizontal и другие функции макета, но игнорирует только энктип. Хрустящая документация вообще не упоминает form_enctype.

Наконец-то решение!

Я наконец-то нашел решение. Это несколько сфальсифицировано, но маленькая клейкая лента никогда не повредит. Смотрите ответ ниже.

enter image description here

1 Ответ

0 голосов
/ 22 октября 2019

Я знал проблему, связанную с полем enctype. Я поместил его в свой FormHelper, но он никогда не передавался в форму во время реальной пользовательской сессии HTML. Поэтому я просто добавил его во вложенный car_create.html файл формы следующим образом:

            <form method="POST" enctype="multipart/form-data">
                {% crispy form %}
            </form>

Формы теперь вложены, но это работает! Я в восторге.

...