For this app, we combine Django (a free, open source framework based on Python) with an REST API (representational state transfer API).
The combination takes places through the Django REST framework (DRF) toolkit.
Since Django utilizes a Model-View-Template (MVT) architectural pattern, the toolkit is able to use the class-based views.
The outcome is a fully functional CRUD Django REST API.
Endpoints define the structure and usage for the GET, POST, PUT, and DELETE HTTP methods within an RESTful API.
This app uses two endpoints:
Endpoint | GET | POST | PUT | DELETE | View |
---|---|---|---|---|---|
todos/api |
1. List All: List all to-dos for requested user | 2. Create: Add a new to-do | N/A | N/A | TodoListApiView |
todos/api/<int:todo_id> |
3. Retrieve: Get a to-do with given todo_id |
N/A | 4. Update: Update a to-do with given todo_id |
5. Delete: Delete a to-do with given todo_id |
TodoDetailApiView |
These endpoints can simply be accessed via their specific urls e.g.:
http://127.0.0.1:8000/todos/api/
http://127.0.0.1:8000/todos/api/2
However, this code also feaures the possibility to submit a new entry via a form submission.
The form is located here: http://127.0.0.1:8000/
The associated view is contact
which renders a from for the todo
model and checks if it is valid.
The @login_required
decorators ensures that only a logged in user can access the form. The logged in user is then automatically associated with the user's submitted task.
The conversion of an Model object into an API-usable format (e.g. JSON) is done via a serializer. The Django REST framework does this via the ModelSerializer class (see serializers.py
).
For the purpose of demonstrating the usage of the fetch API in connection with our endpoints, I have integrated a JavaScript (script.js
).
First we need to acquire our csrf token (as decribed in the documentaion):
// Acquiring the csrf token
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
Afterwards we fetch data from our api endpoint:
// Example of fetching data from our api
fetch("/todos/api/1/", {
method: "get",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
"Accept": "application/json",
"Content-Type": "application/json"
},
}).then(function(response) {
return response.json();
}).then(function(data) {
console.log("Data is ok", data); // log data to console
}).catch(function(ex) {
console.log("parsing failed", ex); // log error to console
});
Since I have implemented the script in the contact.html
header, we get the following log within our console if we visit http://127.0.0.1:8000/
:
If we compare this to what we get with our api endpoint (http://127.0.0.1:8000/todos/api/1/
) we see that they are identical:
The code is based on tutorials: