在Django中为一个帖子上传多个图像

时间:2016-01-09 12:45:48

标签: django image upload submit formset

我是django的初学者。我想创建一个允许用户记录考试和相关图像的应用程序。

所以我尝试根据这个主题http://qasimalbaqali.com/uploading-multiple-images-in-django-for-a-single-post/在Django中上传多个图片。

但按下按钮时没有任何反应 我解释一下我的模特。文档是泛型类。考试是一个文档,一个文档包含文件。

class Document(models.Model):

    class Meta:
        db_table = 'Document'

    slug = models.SlugField(max_length=100)
    user = models.ForeignKey(User)
    level = models.ForeignKey(ClassLevel, null=False, default=1)
    school = models.ForeignKey(School, null=False, default=1)
    nb_views = models.IntegerField(default=0)
    name = models.CharField(max_length=100)
    matter = models.ForeignKey(ClassTopic, null=False, default=1)
    status = models.IntegerField(choices=DOCUMENT_STATUS, default=1)
    creation_date = models.DateTimeField(auto_now_add=True)
    deletion_date = models.DateTimeField(auto_now_add=False, default=None, null=True)

    def __unicode__(self):
        return self.name + " (" + str(self.status) + ") " + self.school.name


class DocumentFile(models.Model):

    class Meta:
        db_table = 'DocumentFile'

    file = models.FileField(upload_to="photo/", null=True)
    document = models.ForeignKey(Document)

    def __unicode__(self):
        return self.file

class Exam(Document):

    class Meta:
        db_table = 'Exam'
    year_exam = models.IntegerField(choices=EXAM_YEAR_CHOICES, default=1)
    mock_exam = models.IntegerField(choices=EXAM_TYPE, default=1)

    def __unicode__(self):
        return self.name + " " + self.matter

我创建了两个表单。用于考试和文件。

class UploadFileForm(ModelForm):

    #description = forms.CharField(max_length=30)

    file = forms.FileInput()

    helper = FormHelper()
    helper.form_id = 'file-input'
    helper.form_show_labels = False
    helper.layout = Layout(PrependedText('file', "", placeholder=""))
    #helper.layout.insert(1, HTML("<input type='file' class='file' multiple data-show-upload='false' data-show-caption='true'>"))

    class Meta:
        model = DocumentFile
        fields = ('file',)
        #exclude = ("file_type", "file_path", "document")

class CreateExamForm(forms.ModelForm):

    helper = FormHelper()
    helper.form_id = 'CreateExam'
    helper.form_show_labels = False
    helper.layout = Layout(
        PrependedText("matter", "", ""),
        PrependedText("level", "<small class='text-warning'>Selectionner la classe. </small>", ""),
        PrependedText("school", "<pre><small>Selectionner l\'établissement. </small></pre>", css_class="selectpicker"),
        PrependedText("year_exam", ""),
        PrependedText("mock_exam", ""))

    class Meta:
        model = Exam
        exclude = ("slug", "user", "nb_views", "name", "status", "creation_date", "deletion_date")

我的观点

def createexam(request):

    # Creation du formulaire + upload des images
    doc_form = CreateExamForm(auto_id=True)

    # Création du formset avec n itération : extra=2
    file_form_set = modelformset_factory(DocumentFile, form=UploadFileForm, extra=1)

    # Récupération du formulaire géré par le mécanisme formset
    #formset = sortedfilesform()

    if request.method == "POST":

        doc_form = CreateExamForm(request.POST)
        files_form = file_form_set(request.POST, request.FILES, queryset=DocumentFile.objects.none())

        if doc_form.is_valid() and files_form.is_valid():
            doc_save = doc_form.save(commit=False)
            doc_save.user = request.user

            for fileform in files_form.cleaned_data:
                image = fileform['file']
                one_image = DocumentFile(document=doc_save, file_value=image)
                one_image.save(commit=False)
            transaction.commit()
            msg = FORM_PROPERTIES.FORM_EXAM_STORED.replace("user", request.user.nickname)
            messages.add_message(request, messages.SUCCESS, msg)
            form = LoginForm()
            context = {'form': form}
            return render_to_response(template_name='login.html', context=context, context_instance=RequestContext(request))
        else:
            messages.add_message(request, messages.SUCCESS, FORM_PROPERTIES.FORM_EXAM_ERROR)
            context = {'doc_form': doc_form, 'file_form_set': file_form_set, }
            return render(request, 'createexam.html', context)
    else:
        context = {'doc_form': doc_form, 'file_form_set': file_form_set, }
        return render(request, 'createexam.html', context)

my url.py

urlpatterns = [
    # Examples:
    url(r'^$', home, name='home'),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', home),
    url(r'^home', home),
    url(r'^login', login),
    url(r'^logout', logout),
    url(r'^register$', register),
    url(r'^createexam$', createexam),
    url(r'^account/reset_password', reset_password, name="reset_password"),
]

我的模板很简单

<div id="login-overlay" class="modal-dialog">
<div class="row">
    <div class="panel panel-info" >
        <div class="panel-heading">
            <div class="panel-title">Créer un examen</div>
        </div>
        <div class="panel-body" >
            <div class="col-sm-12">
            <form id="post_form" method="POST" action='.'
                  enctype="multipart/form-data">

                {% csrf_token %}
                {% for hidden in doc_form.hidden_fields %}
                    {{ hidden }}
                {% endfor %}

                {% for field in doc_form %}
                    {{ field }} <br />
                {% endfor %}

                {{ file_form_set.management_form }}
                {% for form in file_form_set %}
                    {% crispy form %}
                {% endfor %}
                <input type="submit" value="Add recipe" class="submit" />
            </form>
            </div>
        </div>
    </div>
</div>

一切似乎都很好。但我的提交没有想到。 我已经两天了。 我读了很多东西。有人可以帮我吗(抱歉我的英文)

2 个答案:

答案 0 :(得分:1)

这里有一些问题。

首先,您没有在模板中显示表单错误,因此用户无法知道他们的提交无效的原因。确保您在每个字段后执行{{ field.errors }},或者同时对整个表单执行{{ form.errors }};并记住这样做形成主要形式和图像形式集。

其次,您使用commit = False保存表单,因此它们不会持久保存到数据库中。如果你想添加表单中没有包含的额外数据,那么这样做很好,但是你需要记住通过调用例如doc_save.save()来实际持久化对象。

答案 1 :(得分:0)

当我将主要表单正文放在<table> ... </table>

中时,我解决了我的问题
<form id="CreateExamForm" method="POST" enctypr="multipart/form-data">
                {% csrf_token %}
                <table>
                    <div class="panel panel-success">
                        <div class="panel-heading">
                            <h3 class="panel-title">Classe - Matière - Date</h3>
                            <span class="pull-right"><i class="glyphicon glyphicon-chevron-up"></i></span>
                        </div>
                        <div class="panel-body">
                            {% crispy doc_form %}

                            {{ file_form_set.management_form }}
                            {% for f_form in file_form_set %}
                                <div class="form-inline">
                                    {% crispy f_form %}
                                </div>
                            {% endfor %}
                        </div>
                    </div>
                </table>
                <input type="submit" value="Add recipe" class="submit" />
            </form>