需求
集成展示l多环境的log,方便快速定位每天版本的自动化通过率,满足多测试线,多环境,多测试套的log展示。
关系:一条测试线有多台环境,一个环境上有多个测试套,每个测试套对应一个html日志文件
一条测试线的展示样例:
父节点是每个环境,默认显示父节点,点击父节点显示子节点
目前状态
models.py
from datetime import date
from django.db import models
# Create your models here.
MODEL = (
("MDC_3GPP", "MDC_3GPP"),
("MDC_Witen", "MDC_Witen"),
("MDC_Btrunc", "MDC_Btrunc"),
("UDC_3GPP", "UDC_3GPP"),
("UDC_Witen", "UDC_Witen"),
("UDC_Btrunc", "UDC_Btrunc"),
)
class TestLine(models.Model):
TestLine = models.CharField(max_length=20, unique=True, null=False, blank=False, verbose_name="测试线")
class Meta:
verbose_name = "测试线"
verbose_name_plural = "测试线"
def __str__(self):
return self.TestLine
class TestResource(models.Model):
WIN_IP = models.CharField(max_length=200)
JobName = models.CharField(max_length=200, unique=True)
Model = models.CharField(max_length=20, choices=MODEL, default="MDC_3GPP", null=False, blank=False,
verbose_name="制式")
TestLine = models.ForeignKey(TestLine, to_field='TestLine', on_delete=models.PROTECT, verbose_name='测试线')
class Meta:
verbose_name = "测试资源"
verbose_name_plural = "测试资源"
def __str__(self):
return self.JobName
class LogInfo(models.Model):
Suite = models.ForeignKey(TestResource, on_delete=models.PROTECT, to_field='JobName')
TaskName = models.CharField(max_length=200, verbose_name='任务名')
ReportFile = models.FileField(upload_to='%Y-%m-%d', verbose_name='日志文件', blank=True)
Date = models.DateField(default=date.today, null=False, blank=False, verbose_name="日期")
class Meta:
verbose_name = '日志'
verbose_name_plural = "日志"
def __str__(self):
return self.TaskName
views.py
data1 就是data 一个数据库查询的,一个写死的(调试状态),
前段用的bootstrap-table,动态表格
import json
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from ci_report.models import TestResource, LogInfo
def report_home(request):
TestResources = TestResource.objects.all()
data1 = []
id = 1
for i in TestResources:
dic1 = {}
# dic1['time'] = i.Date.strftime('%Y-%m-%d %H:%I:%S')
# dic1["time"] = i.Date.strftime('%Y-%m-%d')
dic1["Name"] = i.JobName
dic1["WIN_IP"] = i.WIN_IP
dic1["id"] = id
dic1["pass"] = '100%'
# dic1["Log"] = 'Log'
dic1["pid"] = ""
# print(dic1)
data1.append(dic1)
logs = LogInfo.objects.filter(Suite=i.JobName)
id += 1
for j in logs:
dic2 = {}
dic2["time"] = j.Date.strftime("%Y-%m-%d")
dic2["Name"] = j.TaskName
dic2["WIN_IP"] = i.WIN_IP
dic2["id"] = id
dic2["pid"] = dic1["id"]
dic2["pass"] = '100%'
dic2["Log"] = j.ReportFile.name
id += 1
# print(dic2)
data1.append(dic2)
data1 = json.dumps(data1)
print(data1)
data = [{
"time": "2019-08-27",
"id": 1,
"Name": "Daily_Iteration_51_Btrunc_15",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": ''
}, {
"time": "2019-08-27",
"id": 2,
"Name": "Install3GPPVersion",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": 1
}, {
"time": "2019-08-27",
"id": 3,
"Name": "Config_3GPP",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": 1
}, {
"time": "2019-08-27",
"id": 4,
"Name": "eapp5_3GPP_Single_Level0_1",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": 1
}, {
"time": "2019-08-27",
"id": 5,
"Name": "send_mail_3gpp_mdc",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": 1
},
{
"time": "2019-08-27",
"id": 6,
"Name": "Daily_Iteration_51_Btrunc_145",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": "",
},
{
"time": "2019-08-27",
"id": 7,
"Name": "send_mail_3gpp_mdc",
"WIN_IP": "10.120.224.221",
"通过率": "100%",
"pid": 6
},
]
data = json.dumps(data)
return render(request, "ci_report/home.html", {"data": data})
home.html
{% extends 'base.html' %}
{% load static %}
{% block title %}日志显示{% endblock %}
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta content="black" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<meta content="email=no" name="format-detection">
<title>系统管理</title>
{# <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">#}
{# <link href="https://cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.css" rel="stylesheet">#}
{# <link rel="stylesheet" href="https://cdn.bootcss.com/jquery-treegrid/0.2.0/css/jquery.treegrid.min.css">#}
</head>
{% block content %}
<div class="container">
<div class="nav nav table">
<ul class="nav">
<li class="nav-item dropdown" data-toggle="pill">
<a class="nav-link active" href="#">Default</a>
</li>
<li class="nav-item dropdown" data-toggle="pill">
{# <a class="nav-link" href="#"></a>#}
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button"
aria-haspopup="true"
aria-expanded="false">测试线一</a>
<div class="dropdown-menu" x-placement="top-start"
style="position: absolute; transform: translate3d(0px, -162px, 0px); top: 0px; left: 0px; will-change: transform;">
<a class="dropdown-item" href="#">MDC_3GPP</a>
<a class="dropdown-item" href="#">MDC_Btrunc</a>
<a class="dropdown-item" href="#">MDC_Witen</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">UDC_3GPP</a>
<a class="dropdown-item" href="#">UDC_Btrunc</a>
<a class="dropdown-item" href="#">UDC_Witen</a></div>
</li>
<li class="nav-item dropdown" data-toggle="pill">
{# <a class="nav-link" href="#"></a>#}
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button"
aria-haspopup="true"
aria-expanded="false">测试线二</a>
<div class="dropdown-menu" x-placement="top-start"
style="position: absolute; transform: translate3d(0px, -162px, 0px); top: 0px; left: 0px; will-change: transform;">
<a class="dropdown-item" href="#">MDC_3GPP</a>
<a class="dropdown-item" href="#">MDC_Btrunc</a>
<a class="dropdown-item" href="#">MDC_Witen</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">UDC_3GPP</a>
<a class="dropdown-item" href="#">UDC_Btrunc</a>
<a class="dropdown-item" href="#">UDC_Witen</a></div>
</li>
</ul>
</div>
</div>
<div class="container">
{# <table class="table table-hover" id="table">#}
<table id="table">
{# <thead>#}
{# <tr>#}
{# <th scope="col">Num</th>#}
{# <th scope="col">Name</th>#}
{# <th scope="col">WIN_IP</th>#}
{# <th scope="col">MDC_IP</th>#}
{# <th scope="col">测试套</th>#}
{# <th scope="col">通过率</th>#}
{# <th scope="col">Log</th>#}
{# </tr>#}
{# </thead>#}
{# <tbody>#}
{# <tr>#}
{# <th scope="row">1</th>#}
{# <td>MDC_Btrunc</td>#}
{# <td>10.120.227.15</td>#}
{# <td>10.10.10.60</td>#}
{# <td><a href="#">Daily_Iteration_51_Btrunc_15</a>#}
{# </td>#}
{# <td>100%</td>#}
{# <td><a href="#">Log</a></td>#}
{# </tr>#}
{# <tr>#}
{# <th scope="row">2</th>#}
{# <td>MDC_Btrunc</td>#}
{##}
{# <td>Jacob</td>#}
{# <td>Thornton</td>#}
{# <td>@fat</td>#}
{# </tr>#}
{# </tbody>#}
</table>
</div>
{# <script src="{% static 'js/jquery.min.js' %}"></script>#}
<script src="{% static 'js/jquery-3.4.1.min.js' %}"></script>
<script src="{% static 'bootstrap/bootstrap-table/bootstrap-table.min.js' %}"></script>
<script src="{% static 'bootstrap/bootstrap-table/bootstrap-table-treegrid.js' %}"></script>
<script src="{% static 'bootstrap/bootstrap-table/jquery.treegrid.min.js' %}"></script>
<script type="text/javascript">
var $table = $('#table');
var data = {{ data|safe }};
console.log(data);
$(function () {
$table.bootstrapTable({
data: data,
idField: 'id',
dataType: 'json',
cache: false,
{#striped: true, //是否显示行间隔色#}
{#showColumns: true,#}
columns: [
{field: 'Name', title: 'Name',},
{field: 'time', title: '时间', width: 140, align: 'center',},
{field: 'WIN_IP', title: 'WIN_IP', align: 'center',},
{field: 'pass', title: '通过率', align: 'center',},
{
field: 'Log', title: 'Log', align: 'center',
formatter: function (value, row, index) {
var suite = row.Log;
console.log(suite);
{#var allTableData = $('#table').bootstrapTable('getData');#}
{#console.log(allTableData);#}
{#a = '<a class="btn btn-success btn-xs" href='+suite+'>log</a> ';#}
a = '<a class="btn btn-success btn-xs" href="#" onclick="">log</a> ';
{#b = '<a class="btn btn-success btn-xs ' + editFlag + '" href="#" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>修改</a> ';#}
return a;
{#return '<a class="btn btn-success btn-xs" href="{% url 'report:report_list' suite %}">log</a> ';#}
{#return [#}
{# '<a class="btn btn-success btn-xs" href="#">log</a>'#}
{#].join("")#}
},
{# var actions = [];#}
{# actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="#" onclick="$.operate.edit(\'' + row.id + '\')"><i class="fa fa-edit"></i>修改</a> ');#}
{# actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="#" onclick="$.operate.remove(\'' + row.id + '\')"><i class="fa fa-remove"></i>删除</a> ');#}
{# actions.push('<a class="btn btn-warning btn-xs " href="#" onclick="createMenuItem(\'' + ctx + '/module/informations/?resourceId='+ row.id + '&type=' +row.resourceType + '\',\'拓片管理\')"><i class="fa fa-remove"></i>拓片管理</a> ');#}
{# return actions.join('');#}
events: {
'click.info':function (ev, value, row, index) {
$(window.alert('11'))
}
}
},
],
//在哪一列展开树形
treeShowField: 'time',
//指定父id列
parentIdField: 'pid',
onResetView: function (data) {
//console.log('load');
$table.treegrid({
initialState: 'collapsed', // 所有节点都折叠
//initialState: 'expanded',// 所有节点都展开,默认展开
treeColumn: 0,
// expanderExpandedClass: 'glyphicon glyphicon-minus', //图标样式
// expanderCollapsedClass: 'glyphicon glyphicon-plus',
onChange: function () {
$table.bootstrapTable('resetWidth');
}
});
//只展开树形的第一级节点
//$table.treegrid('getRootNodes').treegrid('expand');
},
});
});
</script>
{% endblock %}