1

I have a django 4 application and if a a user try to upload a empty file, then this error occurs:

MultiValueDictKeyError at /controlepunt140

'upload_file'

I searched for that error. But it seems that the template is oke. Because the enctype is set correct: enctype="multipart/form-data"

  <form
            class="form-inline"
            action="/controlepunt140"
            method="POST"
            enctype="multipart/form-data">
            <div class="d-grid gap-3">
              <div class="form-group">{% csrf_token %} {{form}}

                <button type="submit" name="form_pdf" class="btn btn-warning">Upload!</button>

              </div>
              <div class="form-outline">              
                <div class="form-group">                 
                  <textarea class="inline-txtarea form-control" id="content" cols="70" rows="25">
  {{content}}</textarea>
                </div>
              </div>
            </div>
          </form>

and views.py:

from __future__ import print_function

import os

from django.conf import settings
from django.shortcuts import render
from django.views import View

from .extracting_text_from_excel import ExtractingTextFromExcel
from .filter_text import FilterText
from .forms import ProfileForm
from .models import UploadFile


 def post(self, *args, **kwargs):
        filter_text = FilterText()
        extract_excel_instance = ExtractingTextFromExcel()
        types_of_encoding = ["utf8", "cp1252"]
        submitted_form = ProfileForm(self.request.POST, self.request.FILES)
        content = ''
        content_excel = ''

        if self.request.POST.get('form_pdf') is not None:
            if submitted_form.is_valid() and self.request.POST:
                uploadfile = UploadFile(
                    image=self.request.FILES["upload_file"])

            uploadfile.save()
            for encoding_type in types_of_encoding:

                with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'r', encoding=encoding_type) as f:
                    if uploadfile.image.path.endswith('.pdf'):
                        content = filter_text.show_extracted_data_from_file(
                            uploadfile.image.path)

                    else:
                        content = f.read()

                return render(self.request, "main/controle_punt140.html", {
                    'form': ProfileForm(),
                    "content": content
                })

            return render(self.request, "main/controle_punt140.html", {
                "form": submitted_form,
            })

and forms.py:

class ProfileForm(forms.Form):
    upload_file = forms.FileField(required=False)

So how to tackle this?

mightycode Newton
  • 3,229
  • 3
  • 28
  • 54
  • 1
    Try changing `if submitted_form.is_valid() and self.request.POST:` to `if submitted_form.is_valid() and self.request.FILES:` – raphael Nov 19 '22 at 20:39
  • @raphael. oh, thank you. This is working. But what is the difference? – mightycode Newton Nov 19 '22 at 20:47
  • 1
    `request.POST` will contain the form data, but will not contain uploaded files, so when the user submits the form, `request.POST` *will be `True` because it has form data, even though there are no files. `request.FILES` is what will be empty, and thus `False` if the form has no files. Glad you got it to work, and glad I was of help. – raphael Nov 19 '22 at 23:13

1 Answers1

1

cf MultiValueDictKeyError in Django

You're executing

                uploadfile = UploadFile(
                    image=self.request.FILES["upload_file"])

Either use try / except to catch the error, or rely on .get(): self.request.FILES.get("upload_file", None)

You might want to check for None before calling UploadFile().


As written, this doesn't make sense:

            if submitted_form.is_valid() and self.request.POST:
                uploadfile = UploadFile(
                    image=self.request.FILES["upload_file"])

            uploadfile.save()

That is, we conditionally define the uploadfile variable, and then unconditionally call one of its methods. That call won't work if the variable is undefined.

J_H
  • 17,926
  • 4
  • 24
  • 44