The file data ends up placed in request.FILES whenevar django handles a file upload.For more on the request object you can check this documentation:request and response objects .In this document you can check how files are stored on disk and in memory and how to customize the default behavior.
Basic file uploads
Consider a simple form which we created,containing a FileField:
from django import forms class UploadFileForm(forms.Form): title = forms.CharField(max_length=50) file = forms.FileField()
A corresponding view which handles this form will receive the data in request.FILES dictionary,which will contain a key for each FileField (or ImageField) in the form.So we can access the data from the above form by request.FILES[‘file’].
Here request.FILES dictionary will contain data only if the request method will declaring the form was POST and the <form> that posted the request has the attribute enctype="multipart/form-data"
.otherwise, request.FILES will not contain any data.
You can simply pass the file data from request into the form as following:
from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import UploadFileForm # Imaginary function to handle an uploaded file. from somewhere import handle_uploaded_file def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): handle_uploaded_file(request.FILES['file']) return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form})
Notice that to bound the data into form,we have passed the request.FILES into the form’s constructor.
Here is a common way a user might handle an uploaded file:
def handle_uploaded_file(f): with open('some/file/name.txt', 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk)
To ensure that large file won’t overwhelm our system’s memory,we also do looping over UploadedFile.chunks() instead of read().
Handling uploaded files with a model
Using a ModelForm, by saving a file on a Model with a FileField will makes this process of file uploading much easier.The file object will be saved to the location which was specified by the upload_to argument of the corresponding FileField when calling form.save():
from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import ModelFormWithFileField def upload_file(request): if request.method == 'POST': form = ModelFormWithFileField(request.POST, request.FILES) if form.is_valid(): # file is saved form.save() return HttpResponseRedirect('/success/url/') else: form = ModelFormWithFileField() return render(request, 'upload.html', {'form': form})
If while writing view,you are constructing an object manually then you can simply assign the file object from request.FILES to the file fields in the model:
from django.http import HttpResponseRedirect from django.shortcuts import render from .forms import UploadFileForm from .models import ModelWithFileField def upload_file(request): if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): instance = ModelWithFileField(file_field=request.FILES['file']) instance.save() return HttpResponseRedirect('/success/url/') else: form = UploadFileForm() return render(request, 'upload.html', {'form': form})
Uploading multiple files
You can upload multiple files using one form field, by setting the multiple HTML attribute of the field’s widget.
from django import forms class FileFieldForm(forms.Form): file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
Then inside the FormView by overriding the post method,you can 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(which you created)
success_url = '...'
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)
This is all about file uploading in django.