Sending POST data to a Django view via AJAX to a REST endpoint
Use JavaScript's fetch to connect to a Django REST API URL
If you want to send some POST data to an endpoint URL using AJAX, say for example, adding employee data to the database via a popup and not via the regular <form>
method, we need to extract the csrf_token
value from the generated input tag.
Template (for eg. add-employee.html) :
{% csrf_token %}
We need to extract the value of the input element that Django generates like this in HTML :
<input type="hidden" name="csrfmiddlewaretoken" value="ktzIX6zdGAhusuPOK5bSHbzfabByXi0q8wu7YfkTX46vFvA5IQvrb9GXUZVqJVEx">
We'll use JavaScript to extract it :
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
These are documented here in Django 4.2 and here in Django 4.0.
When sending the data in JavaScript via fetch
or using a library like axios
, you need to send in the 'X-CSRFToken'
header with the csrftoken
value (which we extracted just now above)
This becomes the JavaScript code which you can temporarily place in the add-employee.html file itself for now wrapped in a <script>
tag.
const BASE_URL = '{{ request.scheme }}://{{ request.get_host }}/';
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
let global_data = { name: "John", age: 31, code: "IN414" };
let submitFormData = () =>
{
const API_URL = BASE_URL + "/api/employee/add";
const request = new Request(
API_URL,
{ headers: { 'X-CSRFToken': csrftoken } }
);
return fetch(request, {
method: 'POST',
mode: 'same-origin',
body: JSON.stringify(global_data) })
.then(response => response.json())
.then(response =>
{
data = response['time']; return data;
});
}
Now in the urls.py file add :
path('api/add', views.api_add, name='api_add'),
And in the views.py file :
from django.shortcuts import render, HttpResponse
import json
def api_add(request):
t1 = datetime.datetime.now()
print(request.body)
if request.method == 'POST':
data = json.loads(request.body)
print(data)
json_obj = json.dumps({ "time": str(datetime.datetime.now() - t1), "method": "post" })
else:
print("Only POST allowed")
json_obj = json.dumps({ "time": str(datetime.datetime.now() - t1), "method": "get" })
result = HttpResponse(json_obj, 'application/json', charset='utf-8')
return result
Now if you run python manage.py runserver
and click on the submit button, you should be able to see a POST XHR request being made in the console of FireFox (Network in Chrome).