This project uses the Django REST Framework to build an API for consumption.
Here is a quick introduction to Django REST Framework and how to make data from your Django models consumable.
With the Django REST Framework (DRF), there are only few additional steps on top of creating a traditional Django App.
- define a serializer.
- A serializer takes data from a database model, or table, and converts it into a JSON format.
- To create a custom serializer, add a file to app level directory tree named
serializer.py
and importserializers
fromrest_framework
. Next, import the model you would like to use as the API data source. - Subclass the
ModelSerializer
fromrest_framework.serializers
and add an inner class calledMeta
. - Inside the inner
Meta
class define the model you would like to use and the fields you want exposed. Note: it is wise to expose theid
field for use in url routing. Django creates theid
field automatically and sets it as the primary key. No need to create an id field manually in your models.
- Now that the serializer is created, add some views in a views.py file in the App directory.
- Traditional django views are used to customize what 'regular' data is sent to the templates. Whereas, Django REST Framework views are used to customize what 'serialized data' is sent to the templates. Django REST Framework, like traditional django ships with generic views. So, I will be using these generic views. generics provide commonly needed behavior. In most cases I will only need to subclass a generic view rather than create my own views.
- Here I am using two views. One view to display all entries in the model (
ListTodo
) subclassed fromgenerics.ListAPIView
. The other view is used to display a single entry (DetailView
) subclassed from generics.RetrieveAPIview. I have two routes inurls.py
defined for these views. The DetailTodo view can be accessed with an additional parameter in the url, the primary key of the entry. In this case theid
that django automatically created. - Inside the views, override the default attributes of
queryset
andserializer_class
with the queryset from the model being used and the serializer created earlier.
With these steps taken, the API is fully functioning, go to '127.0.0.1:8000/api' to see the model data displayed in JSON format. The great thing about Django REST Framework is that is comes with a browseable API. No need to use cURL or Postman for now. Although later on as the API becomes more complex and more customization is needed, those tools can come in handy.
In order for this API become consumble from another domain, we need to install django-cores-headers
. This library automatically includes the correct headers in our HTTP responses based on project settings.
Next update the settings.py
file in three places:
- add
corsheaders
to theINSTALLED_APPS
- add
CorsMiddleware
aboveCommonMiddleWare
in theMIDDLEWARE
setting - create a
CORS_ORIGIN_WHITELIST
The CORS_ORIGIN_WHITELIST
whitelists domains. In my case that setting looks like:
"http://localhost:3000", # default for React
"http://localhost:8000", # default for Django
)
http://localhost:3000
is the default domain for React. This way you can add a React front end.
It is important to make sure that CorsMiddleware
is in the correct place because Middleware settings are loaded from top to bottom.
With that done, all that is left is to build out a simple React App and gather data from the django endoint.
- Assuming React is already installed, create a React app. Also, install axios. Axios will be used instead of FetchAPI.
- In the app.js folder delete every thing and import the modules needed:
import React, { Component } from "react";
import axios from 'axios';
When using React to fetch API's, best practice is to make HTTP requests inside componentDidMount
. So make a function to request the API using axios and call it from inside componentDidMount
.
Lastly, render the component with data from the API, using map()
to iterate over the list of items returned from the API and created HTML elements from them.