我想從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:而不是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, 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 %}
但是,如何使用模板渲染數據? –
爲了渲染模板中的數據,您必須刪除JsonResponse(數據),並僅放入數據。 – Dronix
問題是,如果我只放入'data',那麼我會遇到'parsererror'問題,爲了避免這種情況,我必須擦除'dataType:'json',這樣做會導致'Uncaught TypeError:Can not read property' 0'未定義' –