2017-08-24 3 views
0

Ich versuche, eine JSON-Antwort von einer POST-Anfrage zurückzugeben, aber ich begegne verschiedenen Fehlern im Pfad.Wie kann man einen Json erfolgreich übergeben, um ihn in Django zu rendern und zu manipulieren?

Zuerst habe ich die folgende Ansicht

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)) 

, die die Vorlage tickets_per_day_results.html nennt, die eine Ajax-Request enthält:

$.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) 
    } 

aber diese Kombination wirft mich context must be a dict rather than JsonResponse Fehler.

Ich habe versucht, verschiedene Alternativen:

Alternative 1: Statt JsonResponse ich Response wie folgt verwendet:

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)) 

aber context must be a dict rather than Response die Fehler warf.

Alternative 2: Statt JsonResponse und Response ich das Objekt zu einem dict wie folgt umzusetzen versucht:

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))) 

aber The response content must be rendered before it can be iterated over den Fehler warf.

Alternative 3: Statt 1 und 2 habe ich versucht, Daten zu übergeben, ohne JsonResponse noch 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) 

aber warf den Fehler parsererror von der Ajax-Anforderung, weil dies bedeutet, dass Sie einfach einen String zurückgeben oder ein anderer Wert, es ist nicht wirklich Json, so dass der Parser beim Parsen fehlschlägt. Sie können diesen Fehler vermeiden, indem dataType:'json' von dem Ajax-Request (Lösung von parsererror Ajax) entfernt, aber das wird mich nicht erlauben, meine Datensätze aus meiner Vorlage tickets_per_day_results, das heißt,

entfernen 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) 
    } 

zu manipulieren dann kann ich nicht meine Datensätze manipulieren, die unterhalb der Ajax-Anfrage zu finden sind:

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' 
      }, 

weil Siegefunden.

Das war ein mühsamer Weg und mir sind die Ideen (und Geduld) ausgegangen. Wenn mir jemand eine andere Alternative vorschlagen kann, wird mir das ein wenig helfen.

aktualisieren Tickets pro Tag Ergebnisse HTML-Datei

{% 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 %} 

Antwort

1

Ich denke, dass Sie die falsche Methode zur Rückgabe Daten im JSON-Format verwenden. Im Code:

render(request,template_name,JsonResponse(data)) 

In der Dokumentation von Django here. Die Render-Verknüpfung wird zum Rendern einer Html-Vorlage mit Wörterbuchdaten zum Aktualisieren der Seite verwendet.

Nach dem Django-Code denke ich, dass Sie Django Rest Framework verwenden. Um JSON-Daten zu senden, sollten Sie das Beispiel hier DRF example response verwenden, um JSON-Daten an die Seite zu senden.

+0

Aber wie können Sie die Daten mit der Vorlage rendern? –

+0

Für das Rendern der Daten in der Vorlage müssen Sie die JsonResponse (Daten) entfernen und nur Daten einfügen. – Dronix

+0

Das Problem ist, dass, wenn ich nur 'Daten' stelle, dann werde ich das' parsererror' Problem finden und um dies zu vermeiden, muss ich 'dataType: 'json' löschen und dies führt zum' Uncaught TypeError: Kann nicht lesen' 0 'von undefined' –

Verwandte Themen