• author: BugBytes

Uploading Files to an API Endpoint with Django Ninja

Welcome to the fourth video in our Django Ninja series! In this tutorial, we'll explore how to upload files to an API endpoint using Django Ninja. The Django Ninja documentation provides us with a few objects to help us work with files, specifically the File object and the UploadedFile object, which is an alias to the Django UploadFile you receive when uploading a file to a view in Django. In this video, we'll learn how to work with these objects effectively.

Setting Up the File Upload Form

To start, we need to create a form that allows us to upload a file using a Django template. We'll begin by creating a templates directory within the tracks app. Inside this directory, we'll create an index.html file, initially containing the text "test". Next, we'll create a normal Django view called index that will render this template. This view will take in a request parameter and render the request along with the index.html template. Finally, we'll create a URL that points to this view.

Here's an example of the basic setup:

# views.pydefindex(request):returnrender(request,'tracks/index.html')# urls.pyfromtracks.viewsimportindexurlpatterns=[# ...path('index/',index,name='index'),# ...]

Now, if we navigate to localhost/index, we should see the "test" text displayed on the screen.

Creating the Django Ninja Endpoint

Next, we'll create a Django Ninja endpoint within the api.py file, which contains the CRUD app that we've built until now. We'll add another endpoint that handles a POST request to the upload endpoint. Let's call this endpoint upload.

Here's an example of the code for the upload endpoint:

# api.pyfromninjaimportRouter,UploadedFilerouter=Router()@router.post("/upload")defupload(request,file:UploadedFile=None):data=file.read()# Further processing and manipulation of the file datareturn{"name":file.name,"data":data}

In this example, we import the necessary constructs from Django Ninja, define the upload function, and use the UploadedFile type hint to indicate that the file parameter is expected to be an uploaded file object. The file can be read using the read() method, which will read the entire file into memory as a bytes object. We can then perform any desired operations on this file data.

Finally, we return a simple response containing the file name (file.name) and the decoded data (data). Note that saving the file to the file system is not demonstrated here, as we're focusing on the basic functionality. It's important to consider different approaches, especially for large files, in a production application.

Implementing the File Upload Form

The last step is to create the template that allows users to upload a file. We'll update the existing text in the index.html file to include an HTML form element. The form element's method attribute is set to post, indicating that it will perform a POST request. The action attribute specifies the URL to which the form data should be submitted. In our case, we'll use the {% url %} template tag from Django to dynamically generate the URL.

Here's an example of the updated index.html file:

<!-- index.html --><formmethod="post"enctype="multipart/form-data"action="{% url 'api:upload' %}">
    {% csrf_token %}

Note that we add the enctype="multipart/form-data" attribute to the form element, which allows file uploads. The {% csrf_token %} template tag is included for security reasons. This form will now send a POST request to the upload endpoint we defined in the api.py file when the user submits the form.

Testing the File Upload

To test the file upload functionality, let's reload our frontend and navigate to the index page. You should now see a basic HTML form with a "Browse" button. Click the "Browse" button, select a file to upload (for example, the requirements.txt file), and submit the form.

Upon submission, you should receive a response containing the file name (e.g., requirements.txt) and a string representation of the file data. The file data is obtained by decoding the bytes object we read previously. This demonstrates the basic functionality of reading an uploaded file and returning a response. Remember to explore various ways you can utilize this file data, such as saving it to the file system or performing further operations based on your application's requirements.

Automatic Documentation with Django Ninja

One of the useful features of Django Ninja is its ability to automatically generate documentation for your endpoints. By accessing localhost:8000/api/docs, you'll be presented with the Swagger documentation, which provides information about the available endpoints and their respective request and response structures.

For example, if we go to the upload endpoint, we'll see that it expects a file as a required field. This documentation also provides details on the structure of the response, which can be inferred from the response model. In our case, it's a list of track schema objects.

This automatic documentation can be very useful for developers, as it outlines the expected request body, the structure of the response, and any query parameters, if applicable. It can also be customized to suit your specific needs, although the default setup is already quite powerful.


Congratulations on learning how to upload files to an API endpoint using Django Ninja! In this tutorial, we explored the process of creating a file upload form, implementing the necessary view and URL, and defining a Django Ninja endpoint to handle the file upload. We also briefly covered Django Ninja's automatic documentation feature, which provides valuable documentation for your endpoints.

We hope you found this tutorial helpful. If you enjoyed it, please like and subscribe to our channel. In addition to the video tutorial, we'll be posting related articles on our blog, so be sure to check those out too.

Thank you for watching! See you in the next video!

Previous Post

Fixing Performance Issues in Code: An In-Depth Analysis

Next Post

Future-Proof Your SEO with a Quick and Easy Trick

About The auther

New Posts

Popular Post