Uploading file via API is a very common requirement. In this guide we will learn to build Django Rest Framework File Upload API.
Setup
- Django: 4.2
- Django Rest Framework: 3.14.0
- Project Name:
fileupload
- App Name:
api
Add your app in INSTALLED_APPS
In fileupload/settings.py
INSTALLED_APPS = [ ..... 'rest_framework', 'api', # your django app ]
Update MEDIA path in settings.py
We need to set the path where we want the uploaded files to be stored.
In settings.py
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
Update project’s urls.py file
For Django to be able to serve media files we need to enable this using static
helper function that Django provides. This only works in DEBUG mode and only if folder locations is local. source
In fileupload/urls.py
from django.conf import settings from django.conf.urls.static import static from django.contrib import admin from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('api.urls', namespace='api')), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Model
Let’s create a Model where we store the file path (as file
) and file upload time (as uploaded_on
). So the uploaded file will be stored in media
folder and file
field will contain it’s path.
In your api/models.py
class UploadedFile(models.Model): file = models.FileField() uploaded_on = models.DateTimeField(auto_now_add=True) def __str__(self): return self.uploaded_on.date()
Run the migration
python manage.py makemigrations python manage.py migrate
Serializer
Creating a ModelSerializer for our Model UploadedFile
. ModelSerializer creates serializer fields based on Model passed and comes with buil-in save
method that saves passed data into database.
In your api/serializers.py
from rest_framework import serializers from .models import UploadedFile class FileUploadSerializer(serializers.ModelSerializer): class Meta: model = UploadedFile fields = ('file', 'uploaded_on',)
View
Now we create the view class FileUploadAPIView
(sub-class of APIView) to save the uploaded file. Few things to note:
- Generally the
JSONParser
is set as the default parser in DRF so that we can send the request in JSON format. However it is not advised/convenient to upload file in JSON. form-data
is the best way to upload the file, to enable this we need to passMultiPartParser
andFormParser
as ourparser_classes
in our view.- Just
MultiPartParser
can be passed to enable file uploading but as per DRF API Guide on MultiPartParser, we should use both parser classes to fully support HTML form data.
In api/views.py
from rest_framework import status from rest_framework.parsers import FormParser, MultiPartParser from rest_framework.response import Response from rest_framework.views import APIView from .serializers import FileUploadSerializer class FileUploadAPIView(APIView): parser_classes = (MultiPartParser, FormParser) serializer_class = FileUploadSerializer def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): # you can access the file like this from serializer # uploaded_file = serializer.validated_data["file"] serializer.save() return Response( serializer.data, status=status.HTTP_201_CREATED ) return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST )
Urls
Let’s connect our view in urls to be able to receive requests on it.
In api/urls.py
from django.urls import path from .views import FileUploadAPIView, ImageUploadAPIView app_name = 'api' urlpatterns = [ path('upload-file/', FileUploadAPIView.as_view(), name='upload-file'), ]
Testing API Endpoint
Start the server
python manage.py runserver
Postman

- Method: POST (as per our view)
- URL: http://localhost:8000/api/upload-file/
- Body Type: form-data
- Values to be passed
- file as KEY (change the type to File in dropdown), Browse and select a file for VALUE
cURL
curl --location --request POST 'http://localhost:8000/api/upload-file/' \ --form 'file=@"/path/to/yourfile.pdf"'
NodeJS – Axios
var axios = require('axios'); var FormData = require('form-data'); var fs = require('fs'); var data = new FormData(); data.append('file', fs.createReadStream('/path/to/yourfile.pdf')); var config = { method: 'post', url: 'http://localhost:8000/api/upload-file/', headers: { ...data.getHeaders() }, data : data }; axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); }) .catch(function (error) { console.log(error); });
If you want uploaded media files to be stored in AWS S3 then you can refer to this tutorial.