【问题标题】:How to update your django page by looking for new data in the db?如何通过在数据库中查找新数据来更新您的 django 页面?
【发布时间】:2020-08-24 10:31:35
【问题描述】:

我尝试使用 django 和 chart.js 创建仪表板。

我的模块看起来像:

class Sets(models.Model):

   time = models.DateTimeField(default=timezone.now)
   set1 = models.IntegerField()
   set2 = models.IntegerField()
   set3 = models.IntegerField()

我的观点:

from .function_sum import get_sets
from .models import Sets
def home(request, *args, **kwargs):
   sets = Sets.objects.all()
   time = []
   set1 = []
   set2 = []
   set3 = []

   time, set1, set2, set3= get_sets()

   data = {
       "sets" : sets,
       "time": time,
       "set1": set1,
       "set2": set2,
       "set3": set3
   }

   return render(request, "pages/home.html", data)

class ChartData(APIView):
   authentication_classes = []
   permission_classes = []
   sets = Sets.objects.all()
   time = []
   set1 = []
   set2 = []
   set3 = []

   time, set1 , set2 , set3 = get_sets()


   def get(self, request, format=None):

      data = {
        "time": self.time,
        "set1": self.set1,
        "set2": self.set2,
        "set3": self.set3
       }

       return Response(data)

get_sets 正在从我的 Set 数据表中获取当前数据。

我的 html 文件包含在布局页面中:

<div class="col-xl-6" url-endpoint='{% url "chart-data" %}'>
    <div class="card mb-5">
        <div class="card-header"><i class="fas fa-chart-line mr-1"></i>Chart</div>
        <div class="card-body"><canvas id="SetChart" width="100%" height="40"></canvas></div>
    </div>
</div>



<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.3/dist/Chart.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.min.js" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" crossorigin="anonymous"></script>
<script>
var endpoint ='chart/data'
var labels = []
var set1 = []
var set2 = []
var set3 = []






$.ajax({
    method: "GET",
    url: endpoint,
    
    success: function(data){
        labels = data.time
        set1 = data.set1
        set2 = data.set2
        set3 = data.set3


        var ctx = document.getElementById('SetChart').getContext('2d');
        var startingData = {
                labels: labels,
                datasets: [{
                    label: '1',
                    data: set1,
                    borderColor: 'rgba(255, 0, 0, 1)',
                    backgroundColor: 'rgba(0, 0, 0, 0)',
                    pointStyle : "point",
                    borderWidth: 1
                },{
                    label: '2',
                    data: set2,
                    borderColor: 'rgba(20, 0, 0, 1)',
                    backgroundColor: 'rgba(0, 0, 0, 0)',
                    
                    borderWidth: 1
                },{
                    label: '3',
                    data: set3,
                    borderColor: 'rgba(0, 99, 132, 1)',
                    fill: false,
                    borderWidth: 1
                }]
            }

        var SetChart = new Chart(ctx, { type: 'line', data: startingData, options:{}});
        

    },
    error: function(error_data){
        console.log("error")
        console.log(error_data)
    },
}),

setInterval(function(){

   SetChart.data.labels= data.time
   SetChart.data.datasets[0].data = data.set1
   SetChart.data.datasets[1].data = data.set2
   SetChart.data.datasets[2].data = data.set3

   SetChart.update();
}, 1000);

</script>

我对 django、js、html、chart.js 甚至 python 还是很陌生,所以我所做的几乎所有事情都是从教程中复制和修改的。

当我使用 py manage.py runserver 运行 django 服务器时,我的图表会显示当前数据库数据和标签。 但是,当我在后台运行生成器时,将随机值写入我的设置表时,当我按 F5 时,图表甚至没有更新。仅当我停止服务器并再次运行它时。

如何让我的图表检查数据库中的新数据并每隔几分钟更新一次(最好在数据库更新后立即更新) 我也无法处理弹出和推送功能。实际上我的图表应该只显示我的数据库的最后 10 个数据和标签。

更新

根据我刚刚执行的命令。

我更新了我的 html 并在 var SetChart 之后将以下内容包含在我的 $.ajax 调用中:

        function addLabel(chart,label){
            chart.data.labels.push(label)
            chart.update();
        }

        function addData(chart, data, index) {
            chart.data.datasets[index].data.push(data)
            chart.update();
        }

        function removeData(chart) {
            try{
                chart.data.labels.shift();
                chart.data.datasets.forEach((dataset) => {
                    dataset.data.shift();
                });
                chart.update();
            }
            catch(e){
                console.log(e)

            }
        }

        function updateChart(chart, label, set1, set2, set3){
            addLabel(chart,label)
            addData(chart, set1.slice(-1)[0], 0)
            addData(chart, set2.slice(-1)[0], 1)
            addData(chart, set3.slice(-1)[0], 2)
            removeData(chart);
        }

        setInterval(function(){
            $.ajax({
                method: "GET",
                url: endpoint,
                success: function(data){
                    labels = data.time
                    set1 = data.set1
                    set2= data.set2
                    set3= data.set3
                    updateChart(SetChart, labels.slice(-1)[0], set1, set2, set3) 
                    SetChart.update();
                },
                error: function(error_data){
                    console.log("error")
                    console.log(error_data)
                }
            })
        }, 60000);

并移除了另一个 setIntervall 函数。

【问题讨论】:

    标签: python django chart.js


    【解决方案1】:

    根据您的输入,我猜第一个请求是调用 home 视图并加载初始设置数据 - 然后显示在 html 页面上。另一方面,您正在使用ChartData API 视图。如果这种情况是正确的 - 那么:

    ChartData 中的问题是,这部分time, set1 , set2 , set3 = get_sets() 在 django 初始化时执行一次(如前所述)。您需要的是在每次发送请求时获取集合。并且代码片段正在根据请求在get 方法中执行。

    正确的解决方案如下所示:

    class ChartData(APIView):
       authentication_classes = []
       permission_classes = []
       sets = Sets.objects.all()
    
       def get(self, request, format=None):
          time, set1 , set2 , set3 = get_sets()
    
          data = {
            "time": time,
            "set1": set1,
            "set2": set2,
            "set3": set3
           }
    
           return Response(data)
    

    不需要额外的类变量(self.set1 ...)。并且每次请求到达get方法时都会调用get_sets函数。

    更新(基于评论)

    为了避免每次由 API View 处理请求时加载整个数据 - 我会跟踪在前端收到的最后一条记录,并根据最后一条记录 id(可能有另一个字段)我会获取在你的 id 之后创建的记录'在前端重新跟踪。

    【讨论】:

    • 谢谢,解决了第一个问题。我使用 ChartData API 视图只是为了获取 JSON 数据。我知道这当然不是常见的方式,但它确实有效。你有更新图表的解决方案吗?
    • 您的意思是像问题的更新部分一样吗?
    猜你喜欢
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 2020-08-16
    • 2011-06-05
    • 1970-01-01
    • 2022-09-24
    相关资源
    最近更新 更多