在工作中見過有的人即便使用了Django,依然還在採取json或geojson的文件形式為頁面提供數據,相當於嵌入數據而非載入。下麵是個簡單有效的例子: 先從 model.py 開始 urls.py 建立一個 API 的數據(JSON格式)輸出路徑,另一個給圖像輸出頁面。 views.py 下麵則是 ...
在工作中見過有的人即便使用了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里調整數據。