通过 JSON 将 Django 数据库查询集传递给 Highcharts

Posted

技术标签:

【中文标题】通过 JSON 将 Django 数据库查询集传递给 Highcharts【英文标题】:Passing Django Database Queryset to Highcharts via JSON 【发布时间】:2015-03-04 19:04:12 【问题描述】:

第一次海报,长期读者。我花了很长时间寻找这个问题的答案,这让我认为这是我所缺少的一些基本的东西。

我正在尝试提取数据库表中保存的数据并将其传递给在 Highcharts 图中显示。在检查源代码时,我没有从 Django 或客户端收到任何错误。

使用:Django 1.7 和 Python 3.4

views.py:

#unit/views.py
from django.http import JsonResponse
from django.shortcuts import render
from unit.analysis_funcs import ChartData

def chart_data_json(request):
    data = 
    data['chart_data'] = ChartData.get_data()
    return JsonResponse(data, safe = True)

def plot(request):    
    return render(request, 'unit/data_plot.html', )

get_data() 函数:

#unit/analysis_funcs.py
from unit.models import CheckValve

class ChartData(object):    
    def get_data():
        data = 'serial_numbers': [], 'mass': []

        valves = CheckValve.objects.all()

        for unit in valves:
            data['serial_numbers'].append(unit.serial_number)
            data['mass'].append(unit.mass)

        return data

模板:

<!-- templates/unit/data_plot.html -->
% extends "base.html" %

% block extrahead %
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>
% endblock %

% block rootcontainer %
    <div id="container" style="width:100%; height:400px;"></div>    
% endblock %

% block overwrite %
<!-- Overwrite the base.html jQuery load and put in head for Highcharts to work -->
% endblock %

% block extrajs %
<script>
$(document).ready(function() 

    var options = 
        chart: 
            renderTo: 'container',
            type: 'line'
        ,
        series: []
    ;
    var ChartDataURL = "% url 'chart_data_json' %";
    $.getJSON('ChartDataURL', function(data) 
        options.xAxis.categories = data['chart_data']['serial_numbers'];
        options.series[0].name = 'Serial Numbers';
        options.series[0].data = data['chart_data']['mass'];
        var chart = new Highcharts.Chart(options);
    );

);
</script>
% endblock %

最后是网址:

from unit import views, graphs

urlpatterns = patterns('',

   url(r'^chart_data_json/', views.chart_data_json, name = 'chart_data_json'),

   url(r'^plot/', views.plot, name = 'plot'),

)

一切似乎都在运行,但 Highchart 绘图没有渲染。我认为这是我将 JSON 数据从 view.py 移动到 template.html 的方式,但在盯着它看了这么久之后,我开始眼花缭乱了。

任何帮助都会很棒!

【问题讨论】:

控制台是否收到任何错误? @SebastianBochan 检索站点时没有错误。对主 url 和调用数据的 url 都获得典型的 200 响应 【参考方案1】:

我终于让我的绘图工作了。我发现了这种方法here。感谢Harrison 发布他的方法!

我基于上述方法的新views.py:

def plot(request, chartID = 'chart_ID', chart_type = 'line', chart_height = 500):
    data = ChartData.check_valve_data()

    chart = "renderTo": chartID, "type": chart_type, "height": chart_height,  
    title = "text": 'Check Valve Data'
    xAxis = "title": "text": 'Serial Number', "categories": data['serial numbers']
    yAxis = "title": "text": 'Data'
    series = [
        "name": 'Mass (kg)', "data": data['mass'], 
        "name": 'Pressure Drop (psid)', "data": data['pressure drop'],
        "name": 'Cracking Pressure (psid)', "data": data['cracking pressure']
        ]

    return render(request, 'unit/data_plot.html', 'chartID': chartID, 'chart': chart,
                                                    'series': series, 'title': title, 
                                                    'xAxis': xAxis, 'yAxis': yAxis)

拉取数据库对象和传递数据的快捷功能:

class ChartData(object):    
    def check_valve_data():
        data = 'serial numbers': [], 'mass': [],
                 'pressure drop': [], 'cracking pressure': [], 'reseat pressure': []

        valves = CheckValve.objects.all()

        for unit in valves:
            data['serial numbers'].append(unit.serial_number)
            data['mass'].append(unit.mass)
            data['cracking pressure'].append(unit.cracking_pressure)
            data['pressure drop'].append(unit.pressure_drop)
            data['reseat pressure'].append(unit.reseat_pressure)

        return data   

Harrison 方法的关键是一个映射脚本,用于将 Highcharts js 转换为 Python 模板变量:

% extends "base.html" %

% block extrahead %
    <!-- Load in jQuery and HighCharts -->
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="http://code.highcharts.com/highcharts.js"></script>
% endblock %

% block heading %
    <h1 align="center">Analysis</h1>
% endblock %

% block content %
    <div id= chartID|safe  class="chart" style="height:100px; width:100%"></div>
% endblock %

% block overwrite %
<!-- Overwrite the base.html jQuery load and put in head for Highcharts to work -->
% endblock %

% block extrajs %
<!-- Maps the Python template context variables from views.py to the Highchart js variables -->
<script>
    var chart_id =  chartID|safe 
    var chart =  chart|safe 
    var title =  title|safe 
    var xAxis =  xAxis|safe 
    var yAxis =  yAxis|safe 
    var series =  series|safe 
</script>

<!-- Highchart js. Variable map shown above -->
<script>
$(document).ready(function() 
    $(chart_id).highcharts(
        chart: chart,
        title: title,
        xAxis: xAxis,
        yAxis: yAxis,
        series: series
    );
);
</script>
% endblock %

现在一切正常并正确显示!

【讨论】:

这很棒。但即使我正在使用它。如果 xAxis 是日期,那只是一个问题。尝试格式化,但js无法将其识别为日期。 @peteza33 感谢您回来并使用适合您的解决方案更新帖子。显然,Django + Highchart 集成示例并不多,这篇文章有很大帮助。希望我能多次投票! @peteza33, @user1572215 因为我正在学习更多关于 Django 和 Highcharts 的知识,this post 让我意识到最好只在 js 中保留 highchart 参数,因为 Django 视图不需要定义什么在 x 轴上,在 y 轴上,那是模板中的演示部分。就像在您的代码中一样,render' 中的上下文将仅包括 data['mass']data['pressure drop'] 等。 另外,我意识到最好将数据作为 JSON 发送到模板以避免these 之类的问题

以上是关于通过 JSON 将 Django 数据库查询集传递给 Highcharts的主要内容,如果未能解决你的问题,请参考以下文章

Django Rest 框架:将查询集传递给 Response()

将视图中的 Django 查询集传递给模板

将查询集传递给 django 内联表单中的外键字段

有没有办法将 Django 模型查询集转换为模板中的 json 或 json 字符串?

Django 通过匹配布尔值进行条件查询

Django 将带有外键的查询集转换为 JSON