Передача массива из 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», и я не совсем понимаю, как это сделать.
Итак, вкратце:
- Правильно ли я отправляю данные из jQuery? Правильно - это способ, с которым может справиться Python Django.
- Как мне зациклить указанные данные, чтобы получить доступ к каждому полю данных.
Большое спасибо за любую помощь.
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))
Примечание: я еще не разобрался с ответом, но вышеприведенные действия позволят вам получить доступ к отдельным значениям, которые будут выведены на ваш терминал.