File Uploading In Django-Free Django Tutorials

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.

Leave a Comment

Your email address will not be published. Required fields are marked *