Django: Чтение массива объектов JSON из QueryDict

Как передать составную структуру JSON через AJAX-вызов из JS и на стороне сервера, считать его "очень похожий" структурой данных в python?

Я понимаю, что можно использовать форматирование json (simplejson и т.д.), но я как-то чувствую, что сам QueryDict неправильно или переформатирован в моем случае?

Пример:

При передаче массива объектов JSON [{ "id" : 1}, { "id" : 2}, { "id" : 3}] через представление AJAX в Django QueryDict получает формат:

POST:<QueryDict: {u'json_data[0][id]': [u'1'], u'type': [u'clone'], 
u'csrfmiddlewaretoken': [u'69bb3c434ced31ab301ede04bf491ec0'], 
u'json_data[1][id]': [u'2'], u'json_data[2][id]': [u'3']}>

Как я могу перебирать json_data?

Я хочу получить что-то вроде этого:

POST:<QueryDict: {u'json_data': [{u'id': [u'1']}, {u'id': [u'2']}, {u'id': [u'3']}]},
u'csrfmiddlewaretoken': [u'69bb3c434ced31ab301ede04bf491ec0'], u'type': [u'clone']>

Так что я могу получить доступ к QueryDict в качестве словаря и получить json_data в виде списка и обработать его в определенном порядке: возможно, просто перебирайте их в последовательном порядке списка. Что-то вроде:

ret = request.POST
for item in ret['json_data']:
    process(item['id'])

Фактически значение, которое переходит в process(), может быть другим словарем пар ключей значения вместо числа (1,2,3 и т.д.)

JavaScript:

var test = [{"id": 1},{"id": 2},{"id": 3}];
$.post(
    "/insert_tc",
    {
      json_data: test,
      "type": 'clone',
      "csrfmiddlewaretoken": $csrf_token
    },  
    function(json) {
        //CALLBACK
    },
    "json"
);  

views.py:

def insert_tc(request):
    if request.method == 'POST':       
    ret = request.POST
    type = ret['type']
    list = ret.getlist(ret)

Но список возвращает empty []

Я пробовал простые jumps, load, items, get methods, но ни один из них не помог.

Я даже попробовал jQuery.param(obj, true), но это не то, что я хочу (хотя и немного близко).

Есть ли другой/лучший способ передать составные структуры данных назад и вперед Django ↔ JS через AJAX?

Ответ 1

Вы должны усилить JSON, используя JSON.stringify(). Это преобразует объект JSON в строковый формат, чтобы он мог корректно анализироваться на другом конце. На другом конце вам нужно будет использовать json.loads() для "неинформирования" объекта.

Javascript

var test = [{"id": 1},{"id": 2},{"id": 3}];
$.post(
    "/insert_tc",
    {
      json_data: JSON.stringify(test),
      "type": 'clone',
      "csrfmiddlewaretoken": $csrf_token
    },  
    function(json) {
        //CALLBACK
    },
    "json"
);  

Вид

import json
def insert_tc(request):
    if request.method == 'POST':       
        ret = request.POST
        type = ret['type']
        list = json.loads(ret['json_data'])

Ответ 2

На самом деле это jQuery, а не Django, странно. Ваша переменная test не содержит JSON, а действительные объекты JS. jQuery по самым известным для себя причинам разбирает это в какой-то очень странный формат перед публикацией, следовательно, результат вы получаете. Если вы сделали это вместо этого (обратите внимание на цитаты вокруг всего):

var test = '[{"id": 1},{"id": 2},{"id": 3}]';

вы обнаружите, что получите почти почти QueryDict, который вы ожидаете: единственное, что вам нужно сделать, это позвонить json.loads(ret['json_data']).

Также по причинам, которые я не могу понять. jQuery не содержит никаких функций для преобразования вашего массива объектов в JSON. Для этого вам нужно найти плагин или отдельную библиотеку.