Chart.js 不显示 Django Rest API 数据

Posted

技术标签:

【中文标题】Chart.js 不显示 Django Rest API 数据【英文标题】:Chart.js not displaying Django Rest API data 【发布时间】:2020-06-25 05:30:27 【问题描述】:

我有这样的 django REST 框架的 REST API:

[

    "id": 2,
    "timestamp": "2020-03-04T11:46:10+07:00",
    "vibration": 3,
    "moisture": 70,
    "gps_latitude": "-7.760776",
    "gps_longitude": "110.376113",
    "gyro_x": 6.58,
    "gyro_y": 85.0,
    "gyro_z": -3.9,
    "accelero_x": 6.58,
    "accelero_y": 85.0,
    "accelero_z": -3.9,
    "displacement": 10,
    "node_id": 1
,

    "id": 3,
    "timestamp": "2020-03-05T11:46:10+07:00",
    "vibration": 4,
    "moisture": 40,
    "gps_latitude": "-5.760776",
    "gps_longitude": "115.376113",
    "gyro_x": 5.58,
    "gyro_y": 55.0,
    "gyro_z": -5.9,
    "accelero_x": 5.58,
    "accelero_y": 55.0,
    "accelero_z": -5.9,
    "displacement": 50,
    "node_id": 1
,

    "id": 4,
    "timestamp": "2020-03-12T11:46:10+07:00",
    "vibration": 8,
    "moisture": 90,
    "gps_latitude": "-5.769776",
    "gps_longitude": "125.376113",
    "gyro_x": 7.58,
    "gyro_y": 65.0,
    "gyro_z": -9.9,
    "accelero_x": 4.58,
    "accelero_y": 45.0,
    "accelero_z": -4.9,
    "displacement": 40,
    "node_id": 2
]

这是制作rest API的代码:

models.py from app directory

from django.db import models
from django.contrib.auth.models import User

class Data(models.Model):
   node_id = models.ForeignKey("Node", on_delete=models.CASCADE)
   timestamp = models.DateTimeField()
   vibration = models.IntegerField()
   moisture = models.IntegerField()
   gps_latitude = models.CharField(max_length=250)
   gps_longitude = models.CharField(max_length=250)
   gyro_x = models.FloatField()
   gyro_y = models.FloatField()
   gyro_z = models.FloatField()
   accelero_x = models.FloatField()
   accelero_y = models.FloatField()
   accelero_z = models.FloatField()
   displacement = models.IntegerField()

def __str__(self):
    return self.node_id

class Node(models.Model):
     node_id = models.IntegerField()

这是来自 app 目录的 serializers.py:

serializers.py

from .models import Data,Node
from rest_framework import serializers
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
  id = serializers.IntegerField()
  username = serializers.CharField(max_length=200)
  password = serializers.CharField(max_length=100, style="input_type":"password")
  is_staff = serializers.BooleanField(default=False)

def create(self, validated_data):
    """The function called when you create a new User object/instance"""

    return User.objects.create(**validated_data)

def update(self, instance, validated_data):
    """
    Update and return an existing `User` instance, given the validated data.
    """
    instance.username = validated_data.get('username', instance.username)
    instance.password = validated_data.get('password', instance.password)
    instance.is_staff = validated_data.get('is_staff', instance.is_staff)
    instance.save()
    return instance

class Meta:
    model = User
    fields = ('id', 'username', 'password', 'is_staff')


class DataSerializer(serializers.ModelSerializer):
class Meta:
    model = Data
    fields = '__all__'


class NodeSerializer(serializers.ModelSerializer):
class Meta :
    model = Node
    fields = '__all__'

这是来自应用目录的views.py:

from django.views.generic import View
from django.shortcuts import render
from rest_framework import routers, serializers, viewsets
from rest_framework.response import Response
from restapi.serializers import UserSerializer, DataSerializer, NodeSerializer
from django.contrib.auth.models import User
from restapi.models import Data, Node
from django_filters.rest_framework import DjangoFilterBackend
from django.http import HttpResponse
# Create your views here.

class Charts(View):
  def get(self, request, *args, **kwargs):
    return render(request, 'charts.html')


class UserViewSet(viewsets.ModelViewSet):
 queryset = User.objects.all()
 serializer_class = UserSerializer


class DataViewSet(viewsets.ModelViewSet):
 queryset = Data.objects.all()
 serializer_class = DataSerializer
 filter_backends = [DjangoFilterBackend]
 filterset_fields = ['node_id']


class NodeViewSet(viewsets.ModelViewSet):
 queryset = Node.objects.all()
 serializer_class = NodeSerializer

这是项目目录中的 urls.py:

from django.contrib import admin
from django.urls import path, include
from restapi import views

from django.contrib.auth.models import User
from restapi.models import Data, Node
from rest_framework import routers

from restapi.views import UserViewSet, DataViewSet, NodeViewSet, Charts


router = routers.DefaultRouter()
router.register(r'api/users', UserViewSet)

router.register(r'api/data', DataViewSet)

router.register(r'api/node', NodeViewSet)


urlpatterns = [
  path('admin/', admin.site.urls),
  path(r'', include(router.urls)),
  path(r'api/', include('rest_framework.urls', namespace='rest_framework')),
  path('charts/', Charts.as_view(), name='charts'),
]

这是 chart.js 的代码:

$(document).ready(function()
$.datepicker.setDefaults(
    dateFormat: 'yy-mm-dd'
  );
  $("#firstdatepicker").datepicker();
  $("#lastdatepicker").datepicker();
  $("#filter").click(function() 
    var from_date = $("#firstdatepicker").val();
    var to_date = $("#lastdatepicker").val();
    if (from_date != '' && to_date != '') 
      console.log(from_date, to_date);
      var endpoint = '/api/data'
  $.ajax(
    method: "GET",
    dataType: "json",
    url: endpoint,
    data: 
      from_date: from_date,
      to_date: to_date
    ,
    success: function(data)

      var ctx = document.getElementById("myChart2").getContext('2d');
      var myChart = new Chart(ctx, 
          type: 'line',
          data: 
              labels: data.timestamp,
              datasets: [
                  label: 'moisture',
                  data: data.moisture,
                  backgroundColor: [
                      'rgb(68, 145, 252)'
                  ],
                  borderColor: [
                  '#331698'
                  ],
                  borderCapStyle: 'round',
                  borderWidth: 1
              ]
          ,
          options: 
              reponsive: true,
              scales: 
                  yAxes: [
                      ticks: 
                          beginAtZero:true,
                          max:100,
                          stepSize:10
                      ,
                        scaleLabel: 
                        display:     true,
                        labelString: 'moisture'
                    
                  ],
                  xAxes: [
                          display: true,
                          ticks: 
                            min: from_date,
                            max: to_date,
                          ,
                          type: 'time',
                          time: 
                            displayFormats: 
                              second: 'h:mm:ss a'
                            
                          ,
                        scaleLabel: 
                        display:     true,
                        labelString: 'Date'
                    
                  ]
              
          
      );
    ,
    error: function(error_data)
      console.log(error_data)
    
  );
 else 
  alert("Please Select Date");

  );    )

点子列表:

jango-filter       2.2.0
djangorestframework 3.11.0
get                 2019.4.13
pip                 20.0.2
post                2019.4.13
psycopg2            2.8.4
public              2019.4.13
pytz                2019.3
query-string        2019.4.13
request             2019.4.13
setuptools          40.8.0
sqlparse            0.3.1

我不知道怎么了。数据无法显示在图表上。我是 django 的新手。我正在使用 django 2.2.5

no display data

如果你们想帮助我,我真的很感激你们。对不起,我的英语太差了,我不是本地人。

【问题讨论】:

你有没有尝试一步一步地追踪这个?我会首先尝试弄清楚是否在 API 级别生成了正确的数据(一些简单明了的日志记录有助于一个很好的方法),最终只是在前端打印出 json 数据(实际上是页面上的文本)。也许这听起来简单而无聊,但它可能只是有助于确定在此过程中可能会丢失的内容。 我希望我的 API 可以用于方法“get”和“post”。所以我尝试遵循互联网上的一些教程。我已经使用 postman 使用“post”和“get”方法测试了我的 API,它的工作原理。然后我希望我的 API 上的数据可以使用 API url 端点作为数据源绘制在 chart.js 上。但我认为这样做时有一些错误,但它不会在终端上给出错误,所以我无法弄清楚错误在哪里 【参考方案1】:

在chart.js的代码中,尝试将urlendpoint改为http address

$(document).ready(function()
$.datepicker.setDefaults(
    dateFormat: 'yy-mm-dd'
  );
  $("#firstdatepicker").datepicker();
  $("#lastdatepicker").datepicker();
  $("#filter").click(function() 
    var from_date = $("#firstdatepicker").val();
    var to_date = $("#lastdatepicker").val();
    if (from_date != '' && to_date != '') 
      console.log(from_date, to_date);
      var endpoint = '/api/data'
  $.ajax(
    method: "GET",
    dataType: "json",
    url: "http://your-server:port/api/data/",
    data: 
      from_date: from_date,
      to_date: to_date
    ,
    success: function(data)
      //check the data, if it's already return the correct array mentioned at the beginning of the question
      console.log(data);

      var ctx = document.getElementById("myChart2").getContext('2d');
      var myChart = new Chart(ctx, 
          type: 'line',
          data: 
              labels: data.timestamp,
              datasets: [
                  label: 'moisture',
                  data: data.moisture,
                  backgroundColor: [
                      'rgb(68, 145, 252)'
                  ],
                  borderColor: [
                  '#331698'
                  ],
                  borderCapStyle: 'round',
                  borderWidth: 1
              ]
          ,
          options: 
              reponsive: true,
              scales: 
                  yAxes: [
                      ticks: 
                          beginAtZero:true,
                          max:100,
                          stepSize:10
                      ,
                        scaleLabel: 
                        display:     true,
                        labelString: 'moisture'
                    
                  ],
                  xAxes: [
                          display: true,
                          ticks: 
                            min: from_date,
                            max: to_date,
                          ,
                          type: 'time',
                          time: 
                            displayFormats: 
                              second: 'h:mm:ss a'
                            
                          ,
                        scaleLabel: 
                        display:     true,
                        labelString: 'Date'
                    
                  ]
              
          
      );
    ,
    error: function(error_data)
      console.log(error_data)
    
  );
 else 
  alert("Please Select Date");

  );    )

【讨论】:

以上是关于Chart.js 不显示 Django Rest API 数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 模板中使用 for 循环显示多个 chart.js 图表

在Django模板中使用for循环显示多个chart.js图表

图表未显示在Django应用程序的Web页面上(使用Chart.js)

Django:将日期列表传递给 Chart.js 模板中的 JavaScript

为啥 django-rest-framework 不显示 OneToOneField 数据 - django

chart.js 折线图不显示超过图表中某个点的线