[Fixed]-QueryDict always empty from AJAX POST


Django doesn’t really de-serialize JSON payloads for you. request.POST is meant to be used for HTML posted forms, and the like.

For JSON payloads, you should de-serialize the request body yourself, for example: json.loads(request.body).

(request.body is how you access the raw payload).


As @Sergio told, you need to decode the request.body in you views.py. This is the solution by using Django 3.1 and Fetch.

def myteam_save(request):
    if request.method == 'POST' and request.headers.get("contentType": "application/json"):
        body_unicode = request.body.decode('utf-8')
        received_json = json.loads(body_unicode)

    return JsonResponse(received_json, safe=False)

I am not familiar with AJAX. So I post how typical POST with XHR should be using Fetch. Assuming varKey and varValue is pre-defined variables with value to send as json:

According to official documentation you have to pass it for security reasons.

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));
    return cookieValue;
const csrftoken = getCookie('csrftoken');

Below is actual XHR done by using Fetch:

dict = { [varKey]: varValue }

fetch("", {
    headers: {
        'X-CSRFToken': csrftoken,
        "x-Requested-With": "XMLHttpRequest",
        "Content-Type": "application/json"
    method: 'POST',
    body: JSON.stringify(dict),
    mode: 'same-origin',

Leave a comment