我无法访问Django在JSON中序列化的对象的主键。我的JavaScript看起来像:



function makeLink() {
    recorder && recorder.exportWAV(function (blob) {
        let fd = new FormData;
        fd.append("audio", blob);
        let csrftoken = getCookie('csrftoken');
        let xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                var obj = JSON.parse(this.responseText);
                /*console.log(obj[0].pk);*/
                document.getElementById("result").innerHTML = obj.data[0]['pk'];
            }
        }

        xhr.open('POST', uploadAudio_url , true)
        //alert(uploadAudio_url)
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
        xhr.onload = function () {
            // __log("Audio Uploaded to server succesfully");
        };
        xhr.onerror = function (e) {
            // __log("Error Uploading audio" + e)
        };

        xhr.send(fd);
    });

}





我发送blob数据,它是一个音频文件,以便在后端处理语音。后端处理音频文件并正确过滤对象。然后,它使用JSON中的queryset响应客户端。我对获取对象PK并在图库网格中显示图像感兴趣。

这是我的

Views.py:

def process_speech(recognized_audio):
    speech = recognized_audio
    url = ''  # Is the URL where the user will be redirected once speech is proccessed
    keylist = []
    for key in Keyword.objects.all():
        if(speech.find(key.keyword.lower()) != -1):
            keylist.append(key.keyword)

    print('Identificado Keyword: ', keylist)
    if (speech.find('fotos') != -1 or speech.find('fotografías') != -1):
        print("Reconocido FOTO")
        imagenes_filtered = Imagen.objects.filter(keyword__keyword__in=keylist)
        #print(imagenes_filtered)
        return imagenes_filtered
    if (speech.find('video') != -1):
        print("Reconocido VIDEO")

def upload(request):
    print("Método: ", request.method)
    print("Ajax: ", request.is_ajax())
    if request.method == 'POST':
        if request.FILES.get('audio'):
            record_audio = request.FILES['audio']
            fs = FileSystemStorage()
            filename = fs.save(record_audio.name + ".wav", record_audio)
            uploaded_file_url = fs.url(filename)
            print("File received succesfully")
            speech = decodeSpeech(filename)
            print(speech)
            objects = process_speech(speech)
            data = serializers.serialize('json', objects)
            return HttpResponse(JsonResponse({'data': data}, safe=False),)
        else:
            return render_to_response('index.html', {"errors":"No recognized audio"})
    else:
        return HttpResponseRedirect('/home/')


我得到的Json数据如下:

[
    {
     "model": "Galeria.imagen",
     "pk": 20,
     "fields":
                {"image_width": 6000,
                "image_height": 4000,
                "fichero_imagen": "files/img/lucas-albuquerque-615558-unsplash.jpg",
                "keyword": [17, 18]}
    },
    {
     "model": "Galeria.imagen",
     "pk": 21,
     "fields":
                {"image_width": 5855,
                 "image_height": 3860,
                 "fichero_imagen": "files/img/freestocks-org-794156-unsplash.jpg",
                 "keyword": [18]}
    }
]


我已经尝试过类似的事情:


obj.data [0] .pk
obj.data [0] [pk]
obj.data [0]。['pk']
obj.data.pk [0]


等等,但是我总是不确定。

提前致谢

最佳答案

问题是您要将数据序列化为JSON两次。一次使用data = serializers.serialize('json', objects),再一次使用JsonResponse({'data': data})。创建JsonResponse会从第一个调用中转义JSON,从而将列表变成一个大字符串。

您需要删除嵌套的JsonResponse并直接传递JSON。

objects = process_speech(speech)
data = serializers.serialize('json', objects)
return HttpResponse(data)  # Pass the JSON direct to the HttpResponse


然后,您需要修改Javascript,以便它期望顶级对象是列表(没有data属性):

document.getElementById("result").innerHTML = obj[0]['pk'];

09-05 05:48
查看更多