- 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 %}
<inputtype="file"name="file"><buttontype="submit">Upload</button></form>
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.
Conclusion
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!