Skip to main content

Command Palette

Search for a command to run...

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

Updated
2 min read
A
I am a web developer from Navi Mumbai. Mainly dealt with LAMP stack, now into Django and getting into Laravel and Cloud. Founder of nerul.in and gaali.in

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).

POST http://localhost:8000/api/employee/add