13

I am new to django, I am trying to upload more than one file from the browser and store them somewhere in computer storage but I am not storing them successfully with this code please help me out to find my mistake or improvements that I can do. Thanks in advance to help.

views.py

    from django.shortcuts import render
    from django.http import HttpResponse
    # Create your views here.

    def Form(request):
        return render(request, "index/form.html", {})

    def Upload(request):
        for count, x in enumerate(request.FILES.getlist("files")):
            def process(f):
                with open('/Users/benq/djangogirls/upload/media/file_' + str(count), 'wb+') as destination:
                    for chunk in f.chunks():
                        destination.write(chunk) 
            process(x)
        return HttpResponse("File(s) uploaded!")

app/urls.py

from django.conf.urls import url
from index import views

urlpatterns = [
    url(r'^form/$', views.Form),
    url(r'^upload/$', views.Upload)
]

form.html

<form method="post" action="../upload/" entype="multipart/form-data"> {% csrf_token %}
<input type="file" name="files" multiple />
<input type="submit" value="Upload" />

5
  • You haven't mentioned anything that's wrong with your code, any stack trace or unexpected behaviors could help debug it. Commented Sep 16, 2016 at 6:53
  • I am not getting any file in my storage Commented Sep 16, 2016 at 6:54
  • in my computer storage path that is given here /Users/benq/djangogirls/upload/media/ Commented Sep 16, 2016 at 6:55
  • any alternate would also be appreciated Commented Sep 16, 2016 at 6:58
  • 1
    also, enctype is written with a typo (without c) so the browser defaults to application/x-www-form-urlencoded, resulting in the file content not being included in the HTTP request body, thus server-side code cannot see it Commented Feb 19, 2021 at 20:18

5 Answers 5

21

my model to save Document

class Document(models.Model):
  file = models.FileField('Document', upload_to='mydocs/')

  @property
  def filename(self):
     name = self.file.name.split("/")[1].replace('_',' ').replace('-',' ')
     return name
  def get_absolute_url(self):
     return reverse('myapp:document-detail', kwargs={'pk': self.pk})

you can try a django create view in my code i use this DocumentCreateView

class DocumentCreate(CreateView):
   model = Document
   fields = ['file']

   def form_valid(self, form):
     obj = form.save(commit=False)
     if self.request.FILES:
        for f in self.request.FILES.getlist('file'):
            obj = self.model.objects.create(file=f)

   return super(DocumentCreate, self).form_valid(form)

my form html file

<script>
  $(document).ready(function(){
    $('#id_file').attr("multiple","true");

  })
 </script>
<form method="post" enctype="multipart/form-data" action="">{% csrf_token %}
 {{ form.file }}
 <input type="submit" value="upload" />

</form>
Sign up to request clarification or add additional context in comments.

Comments

9

Answer from official django documentation

 file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

https://docs.djangoproject.com/en/3.0/topics/http/file-uploads/#uploading-multiple-files

1 Comment

This is what I use and works fine un Django==4.1.1 but it is not supported anymore in Django==4.2.1
3

Just an update from Django 3.2 and above. According to docs you have to:

If you want to upload multiple files using one form field, set the multiple HTML attribute of field’s widget:

from django import forms

class FileFieldForm(forms.Form):
    file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

Then override the post method of your FormView subclass to handle multiple file uploads:

from django.views.generic.edit import FormView
from .forms import FileFieldForm

class FileFieldView(FormView):
    form_class = FileFieldForm
    template_name = 'upload.html'  # Replace with your template.
    success_url = '...'  # Replace with your URL or reverse().

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('file_field')
        if form.is_valid():
            for f in files:
                ...  # Do something with each file.
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

Comments

1

As @dnet pointed out. The mistake is in your HTML in the form tag. If you don't specify enctype manually, the files will never get sent out (tested even with latest browser and django 4.2). Unfortunately for you, you didn't close the <form> and you have a spelling mistake in enCtype.

<form method="POST" enctype="multipart/form-data">{% csrf_token %}
    <input type="file" name="posts" multiple>
    <button type="submit">Import</button>
</form>
# in your views.py
def upload_file(request):
   for file in request.FILES.getlist('posts'):
       process(file)  # file is an instance of django.core.files.File
   return redirect('app:wherever')

Comments

0

I was able to solve the multi uploads portion in the create view here: Django Class based UpdateView with Form for Multiple Uploaded Files , however, now the update get function is what I am currently stuck on.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.