Django:实现一个简易的数据面板

参考:http://141.164.39.111:8000/~~~~
image

【实现效果图如上,内容及数据纯属虚构,使用django(数据+接口+图表echarts+页面ajax)】

数据面板能够反映出业务变化,并有助于决策层发出业务调整与决策,那么该如何搭建一个数据面板呢?本文暂忽略掉前期的很多准备工作比如:任务产生背景,确定数据指标,采集数据等。以便文中呈现的内容都与数据和图表有关,我个人理解的实现一个数据面板的主要思路有以下几点。

1.实现思路

  1. 需求背景
  2. 确定数据指标(本文跳过)
  3. 采集数据(本文跳过)
  4. 展示数据(文本重点)

2.搭建一个django项目*

  • 安装django

windows操作系统下使用pip安装

pip install Django

  • 创建django项目

django-admin startproject helloworld

$ cd HelloWorld/
$ tree
.
|-- helloworld		 #项目的容器
|   |-- __init__.py  	#一个空文件,告诉 Python 该目录是一个 Python 包	
|   |-- asgi.py		 #一个 ASGI 兼容的 Web 服务器的入口,以便运行你的项目
|   |-- settings.py  	#该 Django 项目的设置/配置
|   |-- urls.py		 #该Django项目的URL声明,对应输入网址的后面路径
|   `-- wsgi.py		 #一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目
`-- manage.py		 #一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互
  • 创建一个应用

python manage.py startapp dashboard

  • 启动项目

python manage.py runserver 8000

image

3.创建一个html页面*

  • 修改配置文件
# HelloWorld/HelloWorld/settings.py 文件代码:
...

import os
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],       # 修改位置
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...
# 关联js,css
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')		# BASE_DIR 当前项目的路径				
]
...
  • 在helloworld目录下(你的项目目录)创建一个templates和static目录

templates和static两个目录主要存放页面相关的数据,一般来说templates存放html,static存放js、css、图片等,

与settings配置一一对应哈

  • 在templates目录下新建一个index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>菜就要多学习</h1>
</body>
</html>
  • 配置一个路径(告诉电脑,我该怎么找到你(index.html))
# 1.在你的项目也就是helloworld目录下(与settings同级),找到urls.py文件

## HelloWorld/HelloWorld/urls.py 
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('dashboard.urls')), # 新增一行,这一行中的''代表当前无路径,include('dashboard.urls'))代表进入dashboard应用的urls,dashboard是前面创建的app应用,你会发现dashboard目录下并没有urls,所以需要手动在该目录新建一个urls.py
]

## HelloWorld/dashboard/urls.py 添加如下内容
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'), # 这一行中的''代表当前无路径(前面的urls配置也是'',最后拼接起来其实就是127.0.0.1:8000/);views是视图,对应本目录下的views.py文件,views.index就是告诉django我要找什么内容(找index.html);name表示起一个别名
]


## HelloWorld/dashboard/views.py # 声明index.html的位置所在,内容如下:
from django.shortcuts import render, HttpRespons

def index(request):
    return render(request, 'index.html')  # 约定俗成的写法, 其中'index.html'声明index.html文件所在的位置,然后django默认地会去templates目录下找

​ 经过前面这几步步骤,我们创建了一个index.html文件(templates目录下),告诉django该如何找到index.html(urls.py文件),并且告诉django,index.html具体在哪(views.py声明),当然不要忘记了很关键的一步settings.py配置,它指引着views.py寻找index.html的具体方位点。

简单地总结:如何告诉django呈现一个什么样的内容呢?

  1. 创建内容(index.html)
  2. 把内容移动到django可以到达的目的地(settings.py配置)
  3. 设定好一个目地(创建templates和static目录)
  4. 指定路线,告诉django该怎么走(urls.py配置)
  5. 到达目的,找到它,把它呈现出来(views.py)

到此,如果运行runserver没有报异常错误,那么刷新页面将会变成index.html的页面
image

4.美观html页面

前面我们已经创建好了static目录,static目录一般存放图片、js、css、font等等,所以在美观html前,把相关的js、css文件放在该目录下,结构如下:

image

修改index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- href接上static目录 -->
    <link rel="stylesheet" href="/static/css/bootstrap5.0.css"> 
    <link rel="stylesheet" href="/static/css/display.css">
    <script type="text/javascript" src="/static/js/bootstrap5.0.js"></script>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
    <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
    <link rel="stylesheet" href="/static/css/components.css">
        <style type="text/css">
        body {
            <!-- 修改背景图 -->
            background: url('/static/img/blur-bg.jpg') no-repeat center center fixed; 
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row" style="margin-top:15px;">
        <div class="col-md-6">
            <div class="panel">
                <div id="chart1" style="height:300px;"></div>
            </div>
        </div>
    </div>
</div>
</body>
<script>

    var pie_data = {
        'title': '线上反馈问题类别',
        'data': [
                { value: 1, name: '体验类' },
                { value: 2, name: 'BUG类' },
                { value: 5, name: '需求类' },
        ]
    }

    var build_pie = function (id_, chart) {
        // 基于准备好的dom,初始化echarts实例
        option = {
           title: {
                text: chart.title,
                textStyle: {
                    fontWeight: 'normal',              //标题颜色
                    color: 'white'
                },
                x: "left"
            },
          tooltip: {
            trigger: 'item',
            formatter:function (parms){
              var str = parms.marker+""+ parms.data.name+"</br>"+
                "问题个数:"+ parms.data.value+ "个" +"</br>"+
                "占比:"+ parms.percent+"%"+"</br>"
              return  str ;
            },
          },
          legend: {
            orient : 'vertical',
            x : 'right',
            top: '5%',
            textStyle: {
                color:'white',
                fontSize:16
            },
          },
          series: [
            {
              name: '问题类别',
              type: 'pie',
              radius: ['40%', '70%'],
              avoidLabelOverlap: false,
              label: {
                show: false,
                position: 'center'
              },
              labelLine: {
                show: false
              },
              // 修改字体颜色的代码begin
              itemStyle: {
                 normal: {
                    label: {
                          textStyle: {
                            color:'#CCC',
                              fontSize: 12,
                              fontWeight:'bolder'
                          }
                      },
                    labelLine : {
                          lineStyle:{
                            color:'#CCC'
                          }
                      }
                 }
              },
              // 修改字体颜色的代码end
              data: chart.data
            }
          ]
        };
        echarts.init(document.getElementById(id_)).setOption(option);
    }
    build_pie(id_ = 'chart1', chart = pie_data);
</script>
</html>

image

5.规范接口,通过接口传递参数

​ 一般地,在确定数据指标后,接下来需要做数据规范,数据规范由前后端共同讨论制定下来,采集数据由数据分析师来,也就是常说的取数,按照事先确定好的数据指标写好SQL语句,再进一步做数据处理,最后以接口方式传递相关的数据,交由前端页面去展示。

​ 在本案例中,为了简单见效快,前期采集数据的工作暂时跳过,案例中的数据将构建假数据。

  • 再次修改views.py文件,代码如下:
# helloworld/dashboard/views.py
from django.shortcuts import render,HttpResponse
import json

# 新增一个api方法
def api(request):
    """
    虚构的假数据,最后以HttpResponse方法返回
    """
    result = {
            'title': '里程碑需求缺陷分布(当周)',
            'data': [
                {'value': 2, 'name': '功能错误'},
                {'value': 2, 'name': '代码错误'},
                {'value': 10, 'name': '用户界面'},
                {'value': 3, 'name': '建议'},
                {'value': 1, 'name': '需求变动'},
            ],
        }
    data = {
        "ret": 200,
        'data': result,
        'msg': "数据规范"
    }
    return HttpResponse(json.dumps(data))

def index(request):
    return render(request, 'index.html')
  • 再次修改urls.py文件
# helloworld/dashboard/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('api', views.api, name='api'), # 新增
]
  • 访问http://127.0.0.1:8000/api,结果如下:

image

  • 修改index.html文件
<!--helloworld/templates/index.html-->

<!--在index.html的head标签下方追加如下代码 -->
....
<head>
   ....
    <!-- 追加代码,通过ajax读取api接口,完成对页面数据的填充 -->
   <script type="text/javascript">
         window.onload = function () {
            $.get("/api", function (data_json, status) {
                data = JSON.parse(data_json)['data'];
                build_pie(id_ = 'chart1', chart = data)
            })
         }
    </script>
</head> 
....

返回index.html页面刷新,效果图如下:

image

结尾

至此,我们完成了从制作(虚假的)数据,以接口形式返回数据,最后再以页面形式把数据图表内容呈现出来,如果想要实现文中开头的效果图,一方面需要补充数据源,另一方面需加以修饰页面。
最后,我想说,其实独立完成一个数据面板并不难,关键在于怎么理解业务,识别业务中存在的痛点,尝试着把这些痛点拆解为一个个可以量化的小目标,完成小目标,从而实现大目标。

如果你想了解完整的代码,欢迎点评:https://gitee.com/gzrosefinch/data-analysic/tree/master/Django/simple_data_panel

posted @ 2021-11-16 23:05  Rosaany  阅读(345)  评论(0编辑  收藏  举报