Most of the applications require at least one file needs to be upload for a reason, such as, for uploading bulk data or processing file data for business requirement. This example will show you how to upload single or multiple files using Django REST framework. REST is an acronym that stands for Representation State Transfer which works on http/https protocol. It is light weight and delivers data very fast.
I am assuming you have a basic knowledge on Python and Django REST framework before you proceed further down. I am going to show you how to use
Serializer for upload single or multiple files upload using REST API. I am also going to show you how to use
ViewSet for creating views.
In Django framework the file data is placed into
request.FILES. You need a
FileField that a view will handle this and this will receive file data in
request.FILES which is a dictionary containing a key for each
FileField. I am going to use
Serializer class to contain this
Python 3.9.0, Django 3.1.2, djangorestframework 3.12.1 (pip install djangorestframework)
The first thing you need to create project directory. The project name is djangofilesupload which you will create using the following command.
django-admin startproject djangorestfilesupload
Next step is to create an app inside the above project directory to perform files upload operations. Create an app called restfilesupload using the following command. Make sure you execute the following command from the project’s root directory djangorestfilesupload, because you are going to create the following app directory under the project’s root directory.
django-admin startapp restfilesupload
The required project and app structures will be created.
Now you need to add this restfilesupload app into the project settings. So edit the file djangorestfilesupload/djangorestfilesupload/settings.py and add the following line into
INSTALLED_APPS section at the end:
INSTALLED_APPS = [ ... 'restfilesupload.apps.RestfilesuploadConfig', ]
The above line is formed using the file djangorestfilesupload/restfilesupload/apps.py. You will see the RestfilesuploadConfig class in this file with the
name = ‘restfilesupload’.
In the first example, I am going to show you how to upload single file in the server followed by multiple files upload. I am going to use the Postman tool to test the file upload application. You can use any REST client that supports file upload functionality or CURL command to upload file or files.
Serializers in Django allow complex data to be converted to native Python datatypes. Django provides a
Serializer class which gives you a powerful, generic way to control the output of your responses.
Here I am going to create a Serializer class with a
FileField that will store the file object. I have put validation for empty and no limit on file size. The below code is written into serializers.py file under folder djangorestfilesupload/djangorestfilesupload/restfilesupload.
FileSerializer class is used here to serialize the request that has a field called
from rest_framework import serializers class FileSerializer(serializers.Serializer): file = serializers.FileField(max_length=None, allow_empty_file=False)
Here I will write code for views into djangorestfilesupload/djangorestfilesupload/restfilesupload/views.py file. Here I am going to use
ViewSet which will allow me to write multiple views together. If you want you can also create individual view.
You must define the function create() in the
ViewSet otherwise your API root will be blank. By default file will be uploaded into project’s root directory. If you want to change the destination for upload then you can pass as shown below:
file = serializers.FileField(upload_to='your directory name/')
I am doing simple validation whether
file field is there or not in the request as well as whether file has been passed or not in the
FileSerializer. Here I am sending HTTP Status Code 400 (Bad Request) response for any validation fails otherwise I am sending HTTP Status Code 201 (Created).
from rest_framework import viewsets from rest_framework import status from rest_framework.response import Response from restfilesupload.serializers import FileSerializer class FileUploadViewSet(viewsets.ViewSet): def create(self, request): serializer_class = FileSerializer(data=request.data) if 'file' not in request.FILES or not serializer_class.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST) else: handle_uploaded_file(request.FILES['file']) return Response(status=status.HTTP_201_CREATED) def handle_uploaded_file(f): with open(f.name, 'wb+') as destination: for chunk in f.chunks(): destination.write(chunk)
UploadedFile.chunks() instead of using
read() ensures that large files don’t overwhelm your system’s memory.
Ideally the function
handle_uploaded_file() should be put into common utility file, but just for the sake of this example I have kept into the view file.
Next step is to write API endpoint URL in the file djangorestfilesupload/djangorestfilesupload/urls.py.
As I am using viewsets instead of views, I can automatically generate the URL conf for REST API, by simply registering the viewsets with a router class. If you are using individual view then you can configure API URL explicitly.
You must provide basename for the router otherwise you will get an error
basename argument not specified, and could ‘ \.
from django.urls import include, path from rest_framework import routers from restfilesupload import views router = routers.DefaultRouter() router.register(r'file', views.FileUploadViewSet, basename='file') urlpatterns = [ #path('admin/', admin.site.urls), path('upload/', include(router.urls)), ]
Now I am ready to test the API I have built. Let’s fire up the server from the command line using
manage.py runserver. The application will run on default port
8000. If you want to change the default host/port of the server then you can read tutorial Change default host and port in Django server.
I am going to use Postman tool to test REST APIs here. Select the highlighted values as shown in the following image and click on Send button to upload the file:
You will find the file has been uploaded into the root directory (djangorestfilesupload) of the project.
Multiple Files Upload
For upload multiple files you have to do just one thing – get the list of files from the request and iterate each of them to upload. So use the below code snippets instead of
request.FILES['file'] to get all files in the views file. You need to hold CTRL (Windows System) to select multiple files.
The whole source can be downloaded from the Source Code section later.
Now you can test the application by selecting multiple files. All files will be uploaded into the same project’s root directory.
That’s all about how to upload single and multiple files using Django REST API.