如何使Django表单保存图像?

时间:2019-10-20 08:51:25

标签: html django post django-forms django-crispy-forms

我为用户创建了一个上传表单,允许他们创建模型对象。其他所有内容都可以,但是image字段不存储加载的图像。我在views.py中使用了Crispy FormHelper,但是HTML源代码显示未加载元素(enctype, layout_class, field_class etc...)。我认为这就是问题所在。

呈现的表单如下所示:

enter image description here

对于上下文,表单应如下所示:

enter image description here

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

我已经逐行浏览了代码and the tutorial,但是找不到问题所在。

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和其他布局功能,但仅忽略enctype。 Crispy文档完全没有提到form_enctype。

最后,一个解决方案!

我终于找到了解决方案。它有点陪审团,但一点胶带从来没有伤害。请参阅下面的答案。

enter image description here

1 个答案:

答案 0 :(得分:0)

我知道与enctype字段有关的问题。我已经将其放置在FormHelper中,但在实际的HTML用户会话期间从未将其传递到表单中。因此,我将其简单地添加到了封闭的car_create.html表单文件中,如下所示:

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

现在已嵌套表格,但是可以使用!我很高兴