Передача массива из jQuery в представление Django

Я делаю очень маленькое приложение для изучения Django. Я отправляю вложенный массив из jQuery и пытаюсь зациклить его в представлении Django.

Код jQuery выглядит следующим образом:

$(document).on('click','#exModel',function () {
        const sending = [];
       $("table tr").each(function () {

               var p1 =  $(this).find("th label").html();
               var p2 = $(this).find("td input").attr('id');
               var p3 = $(this).find("td input").val();

               const build = [];
               build.push(p1, p2, p3);
               sending.push(build);
               console.log(sending);
           });
       $.ajax({
               url: '../coreqc/exModel/',
               data: {'sending': sending},
               type: 'post',
               headers: {'X-CSRFToken': '{{ csrf_token }}'},
               async: 'true',
               success: function (data) {
                   
                console.log("I made it back")
                        //dom: 'Bfrtip',

               }
                    });
                });

Вышеописанное работает и принимает следующую форму в консоли: Обратите внимание, что 3-е значение намеренно пустое, так как я отправил форму без значений в полях, чтобы получить консольное считывание.

[Log] [["Product A", "1", ""], ["Product B", "2", ""], ["Product C", "3", ""], ["Product D", "4", ""], ["Product E:", "5", ""], ["Product F", "6", ""], ["Product G", "7", ""], ["Product H", "8", ""], ["Product I", "9", ""], ["Product K", "10", ""], …] (36) (coreqc, line 491) 
[Log] I made it back # This is the success text in the above jQuery code

Он попадает в мой вид, и я могу распечатать() вывод в shell:

exModel view:

def exModel(request):
    sentData = request.POST
    print(sentData)

    template = loader.get_template('coreqc/tester.html')
    context = {
    'sentData':sentData
    }
    return HttpResponse(template.render(context, request))

Теперь 'sentData' печатается в оболочке, но это не выглядит правильно, по крайней мере, часть 'sending[1][]' не выглядит правильно. Когда я говорю, что это выглядит неправильно, я не понимаю пустую квадратную скобку. Я не могу получить доступ к отправке, например sending[1][2] - я получаю ошибку ключа словаря.

<QueryDict: {'sending[0][]': ['Product A:', '1', ''], 'sending[1][]': ['Product B', '2', ''], 'sending[2][]': ['Product C', '3', ''], 'sending[3][]': ['Product D', '4', ''], 'sending[4][]': ['Product E', '5', ''], 'sending[5][]': ['Product F', '6', ''], 'sending[6][]': ['Product G', '7', ''], 'sending[7][]': ['Product I', '8', '']}>

Я хотел бы иметь возможность циклически просматривать каждое из значений в QueryDict в моем представлении, а не просто выводить их. Однако я не знаю, как получить к ним доступ и доступно ли то, что отправляется.

get.values() - работает, и я могу печатать в консоль - выглядит так же, как и выше.

Я могу зацикливать и печатать так:

for x, obj in sentData.items():
        print(x)
    
    for y in obj:
        print(y + ':', obj[y])

Однако я получаю только этот вывод, он печатает следующее:

sending[0][]
sending[1][]
sending[2][]
sending[3][]

Мне нужно получить доступ к внутренним значениям, т.е. «Product A», и я не совсем понимаю, как это сделать.

Итак, вкратце:

  1. Правильно ли я отправляю данные из jQuery? Правильно - это способ, с которым может справиться Python Django.
  2. Как мне зациклить указанные данные, чтобы получить доступ к каждому полю данных.

Большое спасибо за любую помощь.

Django разбирает url-encoded данные (т.е. данные с Content-Type application/x-www-form-urlencoded) и сохраняет их в request.POST. Вы отправляете данные в кодировке JSON (application/json). Просто используйте декодер JSON, чтобы разобрать данные:

import json

def exModel(request):
    data = json.loads(request.body)
    ...

Кроме того, хорошей практикой является установка заголовка Content-Type на application/json, хотя в данном случае это не требуется.

После некоторых указаний в другом вопросе выяснилось, что это проблема доступа. Однако советы здесь о json.loads() и request.body() также стали частью ответа. Еще одним дополнением стал JSON.stringify() и то, что вместо вложения массива в массив я вложил объект внутрь массива - не уверен, насколько это изменило ситуацию, но в конечном результате все получилось.

Отправляемый JSON был валидным. После добавления json.loads() и использования request.body вместо request.POST мне все еще нужно было получить доступ к значениям и ключам, о чем я расскажу ниже:

JQuery:

$(document).on('click','#exModel',function () {
        const sending = [];
       $("table tr").each(function () {

               var p1 =  $(this).find("th label").html();
               var p2 = $(this).find("td input").attr('id');
               var p3 = $(this).find("td input").val();

               const build = {bnaa:p1,id:parseInt(p2),vals:parseInt(p3)};
               
               sending.push(build);
              // build.push(p1, p2, p3);
               
           });
        console.log(sending);
        //console.log(JSON.parse(JSON.stringify(sending)));
       $.ajax({
               url: '../coreqc/exModel/',
               data: JSON.stringify({'sending':sending}),
               //data: {'sending':sending},
               //processData: false,
               type: 'POST',
               headers: {'content_type':'application/json','X-CSRFToken': '{{ csrf_token }}'},
              // headers: {'X-CSRFToken': '{{ csrf_token }}'},
               async: 'true',
               success: function (data) {
                   
                console.log("I made it back")
                        //dom: 'Bfrtip',

               }
                    });

Тогда, на мой взгляд:

def exModel(request):
        data = request.body
        data = json.loads(request.body)
        print(type(data))
        for i in range(len(data['sending'])):
            print(data['sending'][i]['bnaa'])
            print(data['sending'][i]['id'])
            print(data['sending'][i]['vals'])

        template = loader.get_template('coreqc/tester.html')
        context = {
        #'blabla':blabla
        }
        return HttpResponse(template.render(context, request))

Примечание: я еще не разобрался с ответом, но вышеприведенные действия позволят вам получить доступ к отдельным значениям, которые будут выведены на ваш терминал.

Вернуться на верх