Django API 为 D3 提供数据

发布时间:2019-05-02 07:04:02编辑:auto阅读(1939)

    在工作中见过有的人即便使用了Django,依然还在采取json或geojson的文件形式为页面提供数据,相当于嵌入数据而非加载。下面是个简单有效的例子:

    先从 model.py 开始

    1 # models.py
    2 from django.db import models
    3 
    4 
    5 class Play(models.Model):
    6     name = models.CharField(max_length=100)
    7     date = models.DateTimeField()

    urls.py 建立一个 API 的数据(JSON格式)输出路径,另一个给图像输出页面。

     1 # urls.py
     2 from django.conf.urls import url
     3 
     4 
     5 from .views import graph, play_count_by_month
     6 
     7 urlpatterns = [
     8     url(r'^$', graph),
     9     url(r'^api/play_count_by_month', play_count_by_month, name='play_count_by_month'),
    10 ]

    views.py

    # views.py
    from django.db import connections
    from django.db.models import Count
    from django.http import JsonResponse
    from django.shortcuts import render
    
    from .models import Play
    
    
    def graph(request):
        return render(request, 'graph/graph.html')
    
    
    def play_count_by_month(request):
        data = Play.objects.all() \
            .extra(select={'month': connections[Play.objects.db].ops.date_trunc_sql('month', 'date')}) \
            .values('month') \
            .annotate(count_items=Count('id'))
        return JsonResponse(list(data), safe=False)

    下面则是HTML部分

     1 <!DOCTYPE html>
     2 <meta charset="utf-8">
     3 <style>
     4 
     5 body {
     6   font: 10px sans-serif;
     7 }
     8 
     9 .axis path,
    10 .axis line {
    11   fill: none;
    12   stroke: #000;
    13   shape-rendering: crispEdges;
    14 }
    15 
    16 .x.axis path {
    17   display: none;
    18 }
    19 
    20 .line {
    21   fill: none;
    22   stroke: steelblue;
    23   stroke-width: 1.5px;
    24 }
    25 
    26 </style>
    27 <body>
    28 <script src="http://d3js.org/d3.v3.js"></script>
    29 <script>
    30 
    31 var margin = {top: 20, right: 20, bottom: 30, left: 50},
    32     width = 960 - margin.left - margin.right,
    33     height = 500 - margin.top - margin.bottom;
    34 
    35 var parseDate = d3.time.format("%Y-%m-%d").parse; // for dates like "2014-01-01"
    36 //var parseDate = d3.time.format("%Y-%m-%dT00:00:00Z").parse;  // for dates like "2014-01-01T00:00:00Z"
    37 
    38 var x = d3.time.scale()
    39     .range([0, width]);
    40 
    41 var y = d3.scale.linear()
    42     .range([height, 0]);
    43 
    44 var xAxis = d3.svg.axis()
    45     .scale(x)
    46     .orient("bottom");
    47 
    48 var yAxis = d3.svg.axis()
    49     .scale(y)
    50     .orient("left");
    51 
    52 var line = d3.svg.line()
    53     .x(function(d) { return x(d.month); })
    54     .y(function(d) { return y(d.count_items); });
    55 
    56 var svg = d3.select("body").append("svg")
    57     .attr("width", width + margin.left + margin.right)
    58     .attr("height", height + margin.top + margin.bottom)
    59   .append("g")
    60     .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    61 
    62 d3.json("{% url "play_count_by_month" %}", function(error, data) {
    63   data.forEach(function(d) {
    64     d.month = parseDate(d.month);
    65     d.count_items = +d.count_items;
    66   });
    67 
    68   x.domain(d3.extent(data, function(d) { return d.month; }));
    69   y.domain(d3.extent(data, function(d) { return d.count_items; }));
    70 
    71   svg.append("g")
    72       .attr("class", "x axis")
    73       .attr("transform", "translate(0," + height + ")")
    74       .call(xAxis);
    75 
    76   svg.append("g")
    77       .attr("class", "y axis")
    78       .call(yAxis)
    79     .append("text")
    80       .attr("transform", "rotate(-90)")
    81       .attr("y", 6)
    82       .attr("dy", ".71em")
    83       .style("text-anchor", "end")
    84       .text("Play count");
    85 
    86   svg.append("path")
    87       .datum(data)
    88       .attr("class", "line")
    89       .attr("d", line);
    90 });
    91 
    92 </script>
    93 </body>
    94 </html>

    输出结果,大家可以在admin里调整数据。

     

关键字