簡(jiǎn)明Python開發(fā)教程(6):用Django搭建網(wǎng)站

前面已經(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è)文件夾,有著一定的模板。

image.png

可以看到目錄結(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是否工作正常。

image.png

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

image.png

1.2 新建一個(gè)應(yīng)用App

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

image.png

這里最重要的是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é)果如下:

image.png

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)更新。完美。


image.png

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è),效果如下:

image.png

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è),效果如下:

image.png

此時(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,效果如下:

點(diǎn)擊前.png

點(diǎn)擊后.png

偶爾可能犯迷糊,參數(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表格式,提供人員技能掌握情況。

image.png

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

image.png

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è)“人員查詢”:

image.png

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

image.png

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容