Reputation: 624
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" />
Upvotes: 12
Views: 57288
Reputation: 423
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')
Upvotes: 0
Reputation: 311
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)
Upvotes: 3
Reputation: 367
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
Upvotes: 8
Reputation: 21
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.
Upvotes: 0
Reputation: 2439
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>
Upvotes: 20