前面已經(jīng)分享了Python的基礎(chǔ)知識(shí)和典型應(yīng)用,那么如何可視化呈現(xiàn)結(jié)果并進(jìn)行交互?
一般用網(wǎng)頁(yè)形式進(jìn)行展示,網(wǎng)頁(yè)展示結(jié)果、交互,服務(wù)器后臺(tái)提供數(shù)據(jù)支持。開發(fā)網(wǎng)站又是一個(gè)復(fù)雜的工作。
幸好Python的Django框架可以讓我們非常容易的搭建網(wǎng)站系統(tǒng),只需要我們學(xué)習(xí)一點(diǎn)點(diǎn)HTML、CSS、JavaScript等前端知識(shí),了解一下Django的工作原理就可以工作了。
前期我們梳理了工作崗位需要掌握的11大類、327小類技能點(diǎn),并對(duì)27位同事的技能掌握進(jìn)行摸底調(diào)查,分為:沒(méi)聽過(guò)、初級(jí)、中級(jí)、高級(jí)四部分;
同時(shí)統(tǒng)計(jì)近5年的外出培訓(xùn)記錄。
目前需要開發(fā)一個(gè)網(wǎng)站,提供查詢功能:
1)按人員查:對(duì)比顯示該同事的技能掌握情況和培訓(xùn)記錄;
2)按技能查詢:顯示不同基本人員分布情況
1 Django介紹
Django是用Python開發(fā)的免費(fèi)開源web框架。
當(dāng)初我使用自強(qiáng)學(xué)堂完成學(xué)習(xí)入門,推薦。
首先需要安裝相應(yīng)版本的Django,如1.11。
如果已經(jīng)安裝Anaconda,那么使用conda intsall django。即可完成安裝。
一般情況,開發(fā)Django應(yīng)用有以下幾步:
1.1 創(chuàng)建一個(gè)工程
使用django-admin.py startproject project_name創(chuàng)建一個(gè)新工程,然后發(fā)現(xiàn)會(huì)自動(dòng)新建一個(gè)文件夾,有著一定的模板。

可以看到目錄結(jié)構(gòu)基本如下:
hrinfo/
manage.py
hrifno/
__init__.py
settings.py
urls.py
wsgi.py
urls.py寫一些url解析規(guī)則,setting.py包含一些全局配置信息,manage.py提供一些管理功能。
如進(jìn)入工程目錄,運(yùn)行開發(fā)環(huán)境,測(cè)試Django是否工作正常。

一切正常,打開瀏覽器,輸入127.0.0.1:8000,結(jié)果如下,說(shuō)明Django工作正常。

1.2 新建一個(gè)應(yīng)用App
進(jìn)入工程目錄后,輸入python manage.py startapp hrskill,可以發(fā)現(xiàn)新建一個(gè)hrskill文件夾,包含若干文件:

這里最重要的是views.py文件,寫網(wǎng)站后臺(tái)處理邏輯。
1.3 修改配置setting.py文件
打開setting.py文件,增加App名稱,如果希望關(guān)聯(lián)數(shù)據(jù)庫(kù),如修改為Mysql
數(shù)據(jù)庫(kù),也可以配置,這里簡(jiǎn)化處理,這里不配數(shù)據(jù)庫(kù)。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hrskill', #新增配置
]
1.4 測(cè)試應(yīng)用功能
通過(guò)修改urls.py 和 views.py來(lái)測(cè)試應(yīng)用是否正常工作。比如我們想訪問(wèn)127.0.0.1:8000時(shí),能夠顯示歡迎語(yǔ)句。
在views.py新增index函數(shù):
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
def index(request):
return HttpResponse(u"歡迎光臨!")
index()返回 HttpResponse 對(duì)象,可以顯示在網(wǎng)頁(yè)上,現(xiàn)在需要規(guī)定那個(gè)網(wǎng)址能使用這個(gè)函數(shù),也就是需要在urls.py進(jìn)行修改:
from django.conf.urls import url
from django.contrib import admin
from hrskill import views as hrskill_views #新增
urlpatterns = [
url(r'^$', hrskill_views.index), #新增url解析規(guī)則,什么網(wǎng)址對(duì)應(yīng)什么函數(shù)
url(r'^admin/', admin.site.urls),
]
其中網(wǎng)址寫法符合正則表達(dá)式規(guī)則。
然后運(yùn)行開發(fā)服務(wù)器 python manage.py runserver,打開瀏覽器,輸入127.0.0.1:8000,結(jié)果如下:

1.5 使用模板(templates)進(jìn)行交互
前面通過(guò)HttpResponse 來(lái)把內(nèi)容顯示到網(wǎng)頁(yè)上,非常簡(jiǎn)單,能做的事也很少。
更多的我們是用模板templates的方法,就是事先寫好html文件,然后直接返回這個(gè)html文件,這樣就可以美化頁(yè)面。
在hrskill文件夾下新建templates文件夾,然后新建一個(gè)index.html文件。
/templates/index.html內(nèi)容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>歡迎使用</title>
</head>
<body>
歡迎跟著朱老師學(xué)Django.
</body>
</html>
然后修改/hrskill/views.py如下:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse #可以注釋掉
def index(request):
return render(request, 'index.html') #修改為這樣即可
#return HttpResponse(u"歡迎光臨!")
然后可以刷新下網(wǎng)頁(yè)(由于之前開發(fā)服務(wù)器一直運(yùn)行,修改views.py會(huì)自動(dòng)生效,無(wú)需重啟,非常方便開發(fā)調(diào)式),結(jié)果已經(jīng)更新。完美。

1.6 對(duì)模板進(jìn)行渲染
上面功能還是很單一,只能返回寫好的html文件。服務(wù)器更強(qiáng)大的應(yīng)該是動(dòng)態(tài)更新html文件,可以交互,比如不同用戶訪問(wèn),通過(guò)后臺(tái)查詢賬號(hào)對(duì)應(yīng)用戶姓名,顯示個(gè)性化歡迎語(yǔ)。
修改/templates/index.html內(nèi)容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>歡迎使用</title>
</head>
<body>
{{name}},歡迎跟著朱老師學(xué)Django.
</body>
</html>
修改/hrskill/views.py如下:
from django.shortcuts import render
def index(request):
name = '朱鋒' #模擬獲取后臺(tái)獲取用戶姓名,這里省略
return render(request, 'index.html',{'name':name}) #注意傳name參數(shù)給前端
刷新網(wǎng)頁(yè),效果如下:

1.7 前端傳參數(shù)給后臺(tái)
很多時(shí)候,用戶需要在前端網(wǎng)頁(yè)輸入某些關(guān)鍵字,然后傳遞給后臺(tái),后臺(tái)根據(jù)這些參數(shù)進(jìn)行處理,并返回結(jié)果。
這里簡(jiǎn)單模擬下用戶在前端網(wǎng)頁(yè)輸入數(shù)字后,后臺(tái)獲取數(shù)字后加10返回,顯示。
首先修改/templates/index.html內(nèi)容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>歡迎使用</title>
<script src="../static/js/jquery-3.2.0.min.js"></script>
</head>
<body>
<p id="p1">歡迎跟著朱老師學(xué)Django.</p>
<form action="/search/" method="get">
<input id="name" type="text" >
<button id='sum' type="button">Go!</button>
</form>
<script>
$(document).ready(function() {
$("#sum").click(function() {
var ne_str = $("#name").val();
$.ajaxSettings.async = false;
$.getJSON("/search/",{"name":ne_str}, function(ret) {
document.getElementById("p1").innerHTML = ret['data']
});
});
});
</script>
</body>
</html>
由于使用Jquery,需要導(dǎo)入,將相應(yīng)js文件放入/hrskill/static/js目錄下(自己新建)。
同時(shí)上面html文件中增加了一個(gè)表單form及對(duì)應(yīng)的動(dòng)作,包括一個(gè)輸入框input,一個(gè)提交按鈕,通過(guò)JavaScript的Ajax技術(shù)獲取后臺(tái)數(shù)據(jù),獲取數(shù)據(jù)后修改p1內(nèi)容。
此時(shí)刷新網(wǎng)頁(yè),效果如下:

此時(shí)點(diǎn)擊Go應(yīng)該沒(méi)有任何反應(yīng),因?yàn)楹笈_(tái)沒(méi)進(jìn)行后臺(tái)修改。
接下來(lái)我們要修改后臺(tái)處理邏輯。
首先增加一個(gè)url網(wǎng)址對(duì)應(yīng)的views函數(shù)。
修改/hringo/urls.py如下:
from django.conf.urls import url
from django.contrib import admin
from hrskill import views as hrskill_views #新增
urlpatterns = [
url(r'^$', hrskill_views.index), #新增url解析規(guī)則,什么網(wǎng)址對(duì)應(yīng)什么函數(shù)
url(r'^search/$', hrskill_views.search), #新增search Url對(duì)應(yīng)view中函數(shù)
url(r'^admin/', admin.site.urls),
]
此時(shí)點(diǎn)擊Go,Django后臺(tái)會(huì)報(bào)錯(cuò),因?yàn)闆](méi)有修改views.py。
修改/hrskill/views.py如下:
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
import json #新增json處理
def index(request):
name = '朱鋒' #模擬獲取后臺(tái)獲取用戶姓名,這里省略
return render(request, 'index.html',{'name':name}) #修改為這樣即可
def search(request): #新增search函數(shù)
name = request.GET['name']
ret = {}
ret['data'] = '你輸入的字符串是——{}'.format(name)
return HttpResponse(json.dumps(ret),content_type='application/json')
現(xiàn)在我們?cè)谳斎肟蜉斎肴魏巫址c(diǎn)擊“Go”,提交后看看效果。(如果沒(méi)響應(yīng),建議重啟開發(fā)服務(wù)器再試試)。
輸入“今天天氣真好”,然后點(diǎn)擊Go,效果如下:


偶爾可能犯迷糊,參數(shù)傳遞有問(wèn)題,重新加載正常,需要前端大牛幫忙解決
以上,我們已經(jīng)簡(jiǎn)單介紹了Django,包括網(wǎng)頁(yè)的基本交互,接下來(lái)就是豐富處理邏輯,美化前端頁(yè)面,都在上面的框架內(nèi)完成。
2 前端優(yōu)化——AdminLTE、Bootstrap、Echarts
為了使前端頁(yè)面更美觀,也使得交互更近優(yōu)化,我們可以學(xué)習(xí)一些基本的前端技術(shù)的使用,如:
Bootstrap簡(jiǎn)潔、直觀、強(qiáng)悍的前端開發(fā)框架,讓web開發(fā)更迅速、簡(jiǎn)單。
AdminLTE,是基于Bootstrap3高度可定制的響應(yīng)式管理模板,是網(wǎng)頁(yè)更簡(jiǎn)單。
Echarts開源免費(fèi)的可視化圖表。
上述工具,自己查看教程學(xué)習(xí),下載相應(yīng)的js文件,放置合適路徑。因?yàn)槲乙仓皇菚?huì)用
3 最終實(shí)現(xiàn)
回到一開始的項(xiàng)目需求,按人員或技能查詢并用合適圖表對(duì)比顯示分析。
首先看看后臺(tái)Mysql兩個(gè)數(shù)據(jù)庫(kù)結(jié)構(gòu):
staff_skill表格式,提供人員技能掌握情況。

training_record表樣例,提供人員培訓(xùn)記錄。

3.1 HTML文件設(shè)計(jì)
總共設(shè)計(jì)3個(gè)html頁(yè)面,分別是首頁(yè)index.html、人員查詢頁(yè)面searchstaff.html和技能查詢頁(yè)面searchskill.html。
下載相應(yīng)的js、css文件,放到/hrskill/static/下合適路徑。
index.html如下(說(shuō)實(shí)話,可能有些css、js文件是不必要,但是我不知道):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>歡迎使用</title>
<link rel="stylesheet" href="../static/css/bootstrap.min.css">
<link rel="stylesheet" href="../static/css/bootstrap-table.min.css">
<link rel="stylesheet" href="../static/css/AdminLTE.min.css">
<link rel="stylesheet" href="../static/css/_all-skins.min.css">
<link rel="stylesheet" href="../static/css/blue.css">
<link rel="stylesheet" href="../static/css/morris.css">
<link rel="stylesheet" href="../static/css/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet" href="../static/css/datepicker3.css">
<link rel="stylesheet" href="../static/css/daterangepicker.css">
<link rel="stylesheet" href="../static/css/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet" href="../static/css/dataTables.bootstrap.css">
<script src="../static/js/jquery-3.2.0.min.js"></script>
<script src="../static/js/bootstrap.min.js"></script>
<script src="../static/js/bootstrap-table.min.js"></script>
<script src="../static/js/bootstrap-table-zh-CN.min.js"></script>
<script src="../static/js/jquery.dataTables.min.js"></script>
<script src="../static/js/dataTables.bootstrap.min.js"></script>
<script src="../static/js/jquery.slimscroll.min.js"></script>
<script src="../static/js/fastclick.min.js"></script>
<script src="../static/js/app.min.js"></script>
<script src="../static/js/demo.js"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<header class="main-header">
<a href="/" class="logo">
<span class="logo-lg">人員技能管理系統(tǒng)</span>
</a>
<nav class="navbar navbar-static-top"></nav>
</header>
<aside class="main-sidebar">
<section class="sidebar">
<ul class="sidebar-menu">
<li class="active treeview">
<a href="#">
<i class="fa fa-th"></i> <span>快速查詢</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li class="active">
<a href="/searchstaff"><i class="fa fa-circle-o"></i>人員查詢</a>
</li>
</ul>
<ul class="treeview-menu">
<li class="active">
<a href="/searchskill"><i class="fa fa-circle-o"></i>技能查詢</a>
</li>
</ul>
</li>
</ul>
</section>
</aside>
<div class="content-wrapper"></div>
</div>
</body>
</html>
人員查詢searchstaff.html文件如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>人員查詢</title>
<link rel="stylesheet" href="../static/css/bootstrap.min.css">
<link rel="stylesheet" href="../static/css/bootstrap-table.min.css">
<link rel="stylesheet" href="../static/css/AdminLTE.min.css">
<link rel="stylesheet" href="../static/css/_all-skins.min.css">
<link rel="stylesheet" href="../static/css/blue.css">
<link rel="stylesheet" href="../static/css/morris.css">
<link rel="stylesheet" href="../static/css/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet" href="../static/css/datepicker3.css">
<link rel="stylesheet" href="../static/css/daterangepicker.css">
<link rel="stylesheet" href="../static/css/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet" href="../static/css/dataTables.bootstrap.css">
<script src="../static/js/jquery-3.2.0.min.js"></script>
<script src="../static/js/bootstrap.min.js"></script>
<script src="../static/js/bootstrap-table.min.js"></script>
<script src="../static/js/bootstrap-table-zh-CN.min.js"></script>
<script src="../static/js/jquery.dataTables.min.js"></script>
<script src="../static/js/dataTables.bootstrap.min.js"></script>
<script src="../static/js/jquery.slimscroll.min.js"></script>
<script src="../static/js/fastclick.min.js"></script>
<script src="../static/js/app.min.js"></script>
<script src="../static/js/demo.js"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<header class="main-header">
<a href="/" class="logo">
<span class="logo-lg">人員技能管理系統(tǒng)</span>
</a>
<nav class="navbar navbar-static-top"></nav>
</header>
<aside class="main-sidebar">
<section class="sidebar">
<ul class="sidebar-menu">
<li class="active treeview">
<a href="#">
<i class="fa fa-th"></i> <span>快速查詢</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li class="active">
<a href="/searchstaff"><i class="fa fa-circle-o"></i>人員查詢</a>
</li>
</ul>
<ul class="treeview-menu">
<li class="active">
<a href="/searchskill"><i class="fa fa-circle-o"></i>技能查詢</a>
</li>
</ul>
</li>
</ul>
</section>
</aside>
<div class="content-wrapper">
<section class="content" >
<form action="/getstaff/" method="get">
<label>姓名:</label>
<input id="name" type="text" >
<button id='sum' class="btn btn-default" type="button">查詢</button>
</form>
<p class="tab-p" id = "remark"></p>
<table id="table" data-checkbox-header="true" data-search="true"></table>
<table id="table_train" data-checkbox-header="true" data-search="true"></table>
</section>
</div>
</div>
<script>
$(document).ready(function() {
$("#sum").click(function() {
var name_str = $("#name").val();
//alert(name_str)
$.ajaxSettings.async = false;
$.getJSON("/getstaff/",{"username":name_str}, function(ret) {
document.getElementById("remark").innerHTML = ret['remark']
var cols = ret['cols']
var a_skills = ret['a_skills']
var cols_train = ret['cols_train']
var train_record = ret['train_record']
var $table = $('#table');
var $table_train = $('#table_train');
$table.bootstrapTable('destroy');
$table_train.bootstrapTable('destroy');
$(function() {
$table.bootstrapTable({
detailView: true,
data: a_skills,
dataType: "json",
search: true, //顯示搜索框
columns: cols,
onExpandRow: function(index, row, $detail) {
InitSubTable(index, row, $detail);
}
});
InitSubTable = function(index, row, $detail) {
var b_skills = row.b_skills;
var cur_table = $detail.html('<table></table>').find('table');
$(cur_table).bootstrapTable({
data: b_skills,
columns: cols,
});
};
});
$(function(){
$table_train.bootstrapTable({
data: train_record,
dataType: "json",
search: true, //顯示搜索框
columns: cols_train,
});
});
});
});
});
</script>
</body>
</html>
通過(guò)輸入被查詢?nèi)藛T姓名,查詢顯示其技能和培訓(xùn)情況。
技能查詢searchsskill.html文件如下:
未完待續(xù),大家可以完成
通過(guò)輸入被查詢技能名稱,查詢顯示人員掌握情況。
3.2 后臺(tái)處理邏輯設(shè)置
修改urls.py如下:
from django.conf.urls import url
from django.contrib import admin
from hrskill import views as hrskill_views #新增
urlpatterns = [
url(r'^$', hrskill_views.index), #新增url解析規(guī)則,什么網(wǎng)址對(duì)應(yīng)什么函數(shù)
url(r'^searchstaff/$', hrskill_views.searchstaff), #新增searchstaff函數(shù)
url(r'^searchskill/$', hrskill_views.searchskill), #新增searchskill函數(shù)
url(r'^admin/', admin.site.urls),
]
修改views.py如下:
from django.shortcuts import render
from django.http import HttpResponse
import pandas as pd
import json #新增json處理
import pymysql #操作數(shù)據(jù)庫(kù)
ip = '127.0.0.1'
user = 'root'
password = 'root'
db = 'hrinfo'
def index(request):
name = '朱鋒' #模擬獲取后臺(tái)獲取用戶姓名,這里省略
return render(request, 'index.html',{'name':name}) #修改為這樣即可
def staffinfo(request):
return render(request, 'searchstaff.html')
def skillinfo(request):
return render(request, 'searchskill.html')
#查詢?nèi)藛T信息
def getstaff(request):
name = request.GET["username"]
conn = pymysql.connect(host=ip, port=3306, user=user, passwd=password, db=db,charset='utf8')
sql_skill = "SELECT * FROM staff_skill"
skills = pd.read_sql(sql_skill,conn)
skills = skills[skills['name']==name]
ret = {}
cols = []
col = ['name','skill_name','date','no','primary','middle','senior']
col_title = ['姓名','技能名稱','認(rèn)證日期','沒(méi)聽過(guò)','初級(jí)','中級(jí)','高級(jí)']
for i in range(len(col)):
col_f = {}
col_f['field'] = col[i]
col_f['title'] = col_title[i]
cols.append(col_f)
ret['cols'] = cols
a_skills = []
for a_skill,group in skills.groupby(['a_skill']):
row = {}
date = max(group['skill_date'])
num = len(group)
no = len(group[group['skill_level']=='沒(méi)聽過(guò)'])
primary = len(group[group['skill_level']=='初級(jí)'])
middle = len(group[group['skill_level']=='中級(jí)'])
senior = len(group[group['skill_level']=='高級(jí)'])
row['name'] = name
row['skill_name'] = a_skill
row['date'] = date
row['no'] = '{}/{}'.format(no,num)
row['primary'] = '{}/{}'.format(primary,num)
row['middle'] = '{}/{}'.format(middle,num)
row['senior'] = '{}/{}'.format(senior,num)
b_skills = []
for b_skill ,b_group in group.groupby(['b_skill']):
b_row = {}
b_row['name'] = name
b_row['skill_name'] = b_skill
b_row['date'] = date
num = len(b_group)
no = len(b_group[b_group['skill_level']=='沒(méi)聽過(guò)'])
primary = len(b_group[b_group['skill_level']=='初級(jí)'])
middle = len(b_group[b_group['skill_level']=='中級(jí)'])
senior = len(b_group[b_group['skill_level']=='高級(jí)'])
b_row['no'] = '{}/{}'.format(no,num)
b_row['primary'] = '{}/{}'.format(primary,num)
b_row['middle'] = '{}/{}'.format(middle,num)
b_row['senior'] = '{}/{}'.format(senior,num)
b_skills.append(b_row)
row['b_skills'] = b_skills
a_skills.append(row)
ret['a_skills'] = a_skills
sql_train = "SELECT * FROM training_record"
trains = pd.read_sql(sql_train,conn)
cj_trains = trains[trains['name']==name]
zj_trains = pd.DataFrame()
for i in trains.index:
speaker = trains.loc[i]['speaker']
if name in speaker:
zj_trains = zj_trains.append(trains.loc[i],ignore_index=True)
re_train = []
if not zj_trains.empty:
for topic in set(zj_trains['train_topic']):
topic_train = zj_trains[zj_trains['train_topic'] == topic][['train_date','days','train_class','train_loc']]
topic_train = topic_train.drop_duplicates()
row = dict(topic_train.iloc[0])
row['name'] = name
row['topic'] = topic
row['isspeaker'] = '是'
re_train.append(row)
if not cj_trains.empty:
for i in cj_trains.index:
topic = cj_trains.loc[i]['train_topic']
if zj_trains.empty or (topic not in set(zj_trains['train_topic'])):
row = dict(cj_trains.loc[i][['train_date','days','train_class','train_loc']])
row['name'] = name
row['topic'] = topic
row['isspeaker'] = '否'
re_train.append(row)
ret['train_record'] = re_train
cols_train = []
col_train = ['name','topic','train_date','days','train_class','train_loc','isspeaker']
col_title_train = ['姓名','培訓(xùn)名稱','培訓(xùn)日期','培訓(xùn)天數(shù)','培訓(xùn)類型','培訓(xùn)地點(diǎn)','是否為講師']
for i in range(len(col_train)):
col_f = {}
col_f['field'] = col_train[i]
col_f['title'] = col_title_train[i]
cols_train.append(col_f)
ret['cols_train'] = cols_train
#寫評(píng)語(yǔ)
num = len(skills)
senior = len(skills[skills['skill_level']=='高級(jí)'])
middle = len((skills[skills['skill_level']=='中級(jí)']))
primary = len((skills[skills['skill_level']=='初級(jí)']))
no = len((skills[skills['skill_level']=='沒(méi)聽過(guò)']))
num_zj = len(zj_trains)
num_cj = len(zj_trains) + len(cj_trains)
remark = "<br>{}同學(xué),在全部的{}個(gè)知識(shí)點(diǎn)中,掌握情況大概如下:高級(jí){}/{},中級(jí){}/{},初級(jí){}/{},沒(méi)聽過(guò){}/{}。\
近期主講{}次培訓(xùn),參加{}次培訓(xùn)。<br>".format(name,num,senior,num,middle,num,primary,num,no,num,num_zj,num_cj)
ret['remark'] = remark
return HttpResponse(json.dumps(ret),content_type='application/json')
由于時(shí)間關(guān)系,后臺(tái)處理邏輯實(shí)現(xiàn)比較亂,建議單獨(dú)一個(gè)模塊,寫各種函數(shù),實(shí)現(xiàn)數(shù)據(jù)處理功能。
現(xiàn)在我們可以看看網(wǎng)頁(yè)的效果
點(diǎn)擊左側(cè)“人員查詢”:

輸入姓名“XX”,點(diǎn)擊查詢:

由于時(shí)間關(guān)系,技能查詢功能未實(shí)現(xiàn),同時(shí)顯示方式、評(píng)價(jià)都有很多優(yōu)化的地方,使得交互更加友好。
期待你們的完善。
全部教程到此結(jié)束,磚已拋出,期待你們的玉。
Python真是零基礎(chǔ)編程的神器!