jquery
  • json
  • ajax
  • django
  • python-3.x
  • 2017-08-24 55 views 0 likes 
    0

    我想從POST請求返回Json響應,但我遇到了路徑中的各種錯誤。如何成功傳遞Json以在Django中渲染和操作它?

    首先,我有以下幾點看法

    class ChartData8(APIView): 
        def tickets_per_day_results(request): 
         if request.method == "POST": 
          template_name = 'personal_website/tickets_per_day_results.html' 
          year = request.POST.get('select_year', None) 
          week = request.POST.get('select_week', None) 
          ....do stuff... 
          data = {"label_number_days": label_number_days, 
            "days_of_data": count_of_days} 
         return render(request,template_name,JsonResponse(data)) 
    

    調用模板tickets_per_day_results.html其中包含一個Ajax請求:

    $.ajax({ 
        method: "POST", 
        url: endpoint, 
        dataType: 'json', 
        contentType: "application/json", 
        headers: {"X-CSRFToken": $.cookie("csrftoken")}, 
        success: function(data){ 
         console.log(data) 
         label_number_days = data.label_number_days 
         days_of_data = data.days_of_data 
         setChart() 
    
        }, 
        error: function(jqXHR,error_data, errorThrown){ 
         console.log("error on data") 
         console.log(error_data) 
         console.log(JSON.stringify(jqXHR)) 
         console.log("AJAX error: " + error_data + ' : ' + errorThrown) 
        } 
    

    但這個組合拋出我context must be a dict rather than JsonResponse錯誤。

    我嘗試過各種替代方案:

    選擇1:而不是JsonResponse我以前Response類似如下:

    class ChartData8(APIView): 
        def tickets_per_day_results(request): 
         if request.method == "POST": 
          template_name = 'personal_website/tickets_per_day_results.html' 
          year = request.POST.get('select_year', None) 
          week = request.POST.get('select_week', None) 
          ....do stuff... 
          data = {"label_number_days": label_number_days, 
            "days_of_data": count_of_days} 
         return render(request,template_name,Response(data)) 
    

    但這拋出了錯誤context must be a dict rather than Response

    備選方案2:而不是JsonResponseResponse我試圖將對象轉換爲一個字典如下所示:

    class ChartData8(APIView): 
        def tickets_per_day_results(request): 
         if request.method == "POST": 
          template_name = 'personal_website/tickets_per_day_results.html' 
          year = request.POST.get('select_year', None) 
          week = request.POST.get('select_week', None) 
          ....do stuff... 
          data = {"label_number_days": label_number_days, 
            "days_of_data": count_of_days} 
         return render(request,template_name, dict(Response(data))) 
    

    但這拋出了錯誤The response content must be rendered before it can be iterated over

    方案3:而不是1和2我試圖通過數據,而不JsonResponse也不Response

    class ChartData8(APIView): 
        def tickets_per_day_results(request): 
         if request.method == "POST": 
          template_name = 'personal_website/tickets_per_day_results.html' 
          year = request.POST.get('select_year', None) 
          week = request.POST.get('select_week', None) 
          ....do stuff... 
          data = {"label_number_days": label_number_days, 
            "days_of_data": count_of_days} 
         return render(request,template_name, data) 
    

    但這從Ajax請求拋出錯誤parsererror,因爲這意味着你只需返回一個字符串或其他值,它不是真的Json,所以分析器解析它時失敗。您可以通過Ajax請求刪除dataType:'json'(從parsererror Ajax溶液)避免這個錯誤,但是這不會讓我從我的模板處理我的數據集tickets_per_day_results,就是

    刪除dataType:json

    $.ajax({ 
        method: "POST", 
        url: endpoint, 
        headers: {"X-CSRFToken": $.cookie("csrftoken")}, 
        success: function(data){ 
         console.log(data) 
         label_number_days = data.label_number_days 
         days_of_data = data.days_of_data 
         setChart() 
    
        }, 
        error: function(jqXHR,error_data, errorThrown){ 
         console.log("error on data") 
         console.log(error_data) 
         console.log(JSON.stringify(jqXHR)) 
         console.log("AJAX error: " + error_data + ' : ' + errorThrown) 
        } 
    

    然後,我不能操縱我的數據集,它們發現下面的Ajax請求:

    data: { 
         labels: label_number_days, 
         datasets : 
          [{ 
           label: 'User_001', 
           data [days_of_data[0],days_of_data[1],days_of_data[2],days_of_data[3],days_of_data[4],days_of_data[5],days_of_data[6]], 
           backgroundColor: 'rgba(255, 99, 132, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    

    ,因爲你發現Uncaught TypeError: Cannot read property '0' of undefined

    這是一個單調乏味的路徑,我缺乏想法(和耐心)。如果任何人都可以建議我任何其他選擇,那麼這會給我一些健康的救濟。

    更新每天結果的html文件

    {% extends "personal_website/header.html"%} 
    
    <script> 
    {% block jquery %} 
    
    var endpoint = '/tickets_per_day_results/' //This works with the chart_data view. 
    
    var days_of_data = [] 
    var label_number_days = [] 
    
    $.ajax({ 
        method: "POST", 
        url: endpoint, 
        dataType: 'json', 
        contentType: "application/json", 
        headers: {"X-CSRFToken": $.cookie("csrftoken")}, 
        success: function(data){ 
         console.log(data) 
         label_number_days = data.label_number_days 
         days_of_data = data.days_of_data 
         setChart() 
    
        }, 
        error: function(jqXHR,error_data, errorThrown){ 
         console.log("error on data") 
         console.log(error_data) 
         console.log(JSON.stringify(jqXHR)) 
         console.log("AJAX error: " + error_data + ' : ' + errorThrown) 
        } 
    }) 
    function setChart() 
    {var ctx_tickets_per_day  = document.getElementById("tickets_per_day") 
    
    var tickets_per_day = new Chart(ctx_tickets_per_day, { 
        showTooltips: false, 
        type:'bar', 
        data: { 
         labels: label_number_days, 
         datasets : 
          [{ 
           label: 'Oscar Gil', 
           data: [days_of_data[0],days_of_data[1],days_of_data[2],days_of_data[3],days_of_data[4],days_of_data[5],days_of_data[6]], 
           backgroundColor: 'rgba(255, 99, 132, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
          { 
           label: 'Oscar Rodriguez', 
           data: [days_of_data[7],days_of_data[8],days_of_data[9],days_of_data[10],days_of_data[11],days_of_data[12],days_of_data[13]], 
           backgroundColor: 'rgba(54, 162, 235, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Animesh Rathore', 
           data: [days_of_data[14],days_of_data[15],days_of_data[16],days_of_data[17],days_of_data[18],days_of_data[19],days_of_data[20]], 
           backgroundColor: 'rgba(255, 206, 86, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Bhaskar Sharma', 
           data: [days_of_data[21],days_of_data[22],days_of_data[23],days_of_data[24],days_of_data[25],days_of_data[26],days_of_data[27]], 
           backgroundColor: 'rgba(75, 192, 192, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Victor Catacora', 
           data: [days_of_data[28],days_of_data[29],days_of_data[30],days_of_data[31],days_of_data[32],days_of_data[33],days_of_data[34]], 
           backgroundColor: 'rgba(153, 102, 255, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Jimmy Gonzalez', 
           data: [days_of_data[35],days_of_data[36],days_of_data[37],days_of_data[38],days_of_data[39],days_of_data[40],days_of_data[41]], 
           backgroundColor: 'rgba(236, 115, 9, 1)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Piyush Gupta', 
           data: [days_of_data[42],days_of_data[43],days_of_data[44],days_of_data[45],days_of_data[46],days_of_data[47],days_of_data[48]], 
           backgroundColor: 'rgba(185, 29, 12, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Carlos Prieto', 
           data: [days_of_data[49],days_of_data[50],days_of_data[51],days_of_data[52],days_of_data[53],days_of_data[54],days_of_data[55]], 
           backgroundColor: 'rgba(105, 129, 64, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          { 
           label: 'Daniel Estrada', 
           data: [days_of_data[56],days_of_data[57],days_of_data[58],days_of_data[59],days_of_data[60],days_of_data[61],days_of_data[62]], 
           backgroundColor: 'rgba(15, 199, 84, 0.6)', 
           borderColor: '#777', 
           borderWidth: 1, 
           hoverBorderWidth: 3, 
           hoverBorderColor: '#000' 
          }, 
    
          ] 
         }, 
         options: { 
          scales: { 
          yAxes: [{ 
           ticks: { 
            beginAtZero: true 
           } 
          }] 
          }, 
    
          title: { 
          display: true, 
          text: 'Tickets by engineer per day', 
          fontSize: 30 
          }, 
         legend: { 
          position: 'right', 
          display: true, 
          labels: { 
           fontColor: '#000' 
           } 
          }, 
          layout: { 
           padding: { 
            left: 50, 
            right: 0, 
            bottom: 0, 
            top: 0 
            } 
          }, 
          tooltips: { 
           enabled: true 
          }, 
    
          hover : { 
          animationDuration: 0 
          }, 
    
          animation: { 
          duration: 0.8, 
          onComplete: function(){ 
           var chartInstance = this.chart, 
           ctx = chartInstance.ctx; 
           Chart.defaults.global.defaultFontColor = '#777'; 
           ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 
              Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily); 
           ctx.textAlign = 'center'; 
           ctx.textBaseline = 'bottom'; 
    
           this.data.datasets.forEach(function (dataset, i) { 
           var isHidden = dataset._meta[0].hidden; //'hidden' property of dataset 
           if (!isHidden) { //if dataset is not hidden 
            var meta = chartInstance.controller.getDatasetMeta(i); 
            meta.data.forEach(function (bar, index) { 
             var data = dataset.data[index]; 
             ctx.fillText(data, bar._model.x, bar._model.y - 5);}); 
            }}); 
          } 
          } 
         } 
        }) 
    } 
    
    {% endblock %} 
    

    {% block content %} 
    
    <div class ='row'> 
    
        {% csrf_token %} 
    <div class="col-sm-12" url-endpoint='{% url "tickets_per_day_results" %}'> 
         <div> 
          <canvas id="tickets_per_day" width="800" height="500"></canvas> 
         </div> 
    </div> 
    </div> 
    {% endblock content %} 
    

    回答

    1

    我認爲你使用了錯誤的方法,以JSON格式返回數據 門票。 在代碼:

    render(request,template_name,JsonResponse(data)) 
    

    在Django中here的文檔。渲染快捷方式用於使用字典數據呈現Html模板以更新頁面。

    根據django代碼,我猜你使用Django rest框架。 爲了發送JSON數據,你應該使用這裏的例子DRF example response爲了發送JSON數據到頁面。

    +0

    但是,如何使用模板渲染數據? –

    +0

    爲了渲染模板中的數據,您必須刪除JsonResponse(數據),並僅放入數據。 – Dronix

    +0

    問題是,如果我只放入'data',那麼我會遇到'parsererror'問題,爲了避免這種情況,我必須擦除'dataType:'json',這樣做會導致'Uncaught TypeError:Can not read property' 0'未定義' –

    相關問題