一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

只需一招,Python 將系統(tǒng)秒變在線版!

 Python技術(shù) 2021-08-18

來源:Python 技術(shù)「ID: pythonall」

上一期,談了如何用 Python 打造運營系統(tǒng) 的過程,雖然以及很方便了,但是還有很多需要人工執(zhí)行的地方,不是特別方便。

更重要的是無法及時為大家提供實時數(shù)據(jù),加上有時工作繁忙可以忘掉,實屬不便。

那么再進一步 —— 做成在線版的,可以隨時瀏覽,方便快捷,還等什么,開干吧。

規(guī)劃

上一期,做的工作主要是數(shù)據(jù)整合,數(shù)據(jù)處理,報表數(shù)據(jù)輸出,已經(jīng)做了大部分工作,現(xiàn)在的問題是如何 Web 化。

Web 化的主要目的是,讓用戶通過瀏覽器訪問到報表數(shù)據(jù),所以改造的重點在于將數(shù)據(jù)展示部分的用前端技術(shù)實現(xiàn)。

于是需要做的是,設(shè)計展示頁面,定義與后端的 數(shù)據(jù)接口,選擇服務(wù)器 部署

而其中重點的工作是 展示頁面 和 數(shù)據(jù)接口。

在進行具體工作之前,還有個一個重要工作就是 —— 選擇技術(shù)路線,即用什么技術(shù)做 Web 化實現(xiàn)。

那需要基于 Python 的 Web 框架來說,可以選擇 Flask 和 Django。

鑒于項目比較小,另外之前寫了一系列 Flask 的文章[1],對 Flask 比較熟,所以選擇了 Flask。

然后將之前實現(xiàn)的功能作為 Web 項目的外部模塊引入,承擔(dān)數(shù)據(jù)讀取任務(wù)。

因為 Web 服務(wù)主要是通過數(shù)據(jù)讀取的,對于打卡數(shù)據(jù)的抓取,和成員積分的計算,需要定時任務(wù)來完成,雖然可以在 Web 服務(wù)中利用 scheduled 來寫計劃任務(wù),為了簡便,直接使用 Linux 服務(wù)的 crontab[2] 命令來定時執(zhí)行。

展示頁面

之前寫過一篇 nginx 日志可視化,其中用的是 Bootstrap 的前端框架,直接拿來用。

真是,平時多積累,用時顯身手!

需要的頁面有 打卡頁面、成員數(shù)據(jù)、組長數(shù)據(jù)、開單記錄。

從哪里開始呢?不是具體的頁面,而是從制作模板頁面開始。

模板頁面

實現(xiàn)前臺功能,比較省力的方式是使用模板,即,將頁面共同的元素寫在模板上,以重復(fù)利用。

創(chuàng)建一個頁面模板 layout.html,模板中寫完頁面主題框架,以及引入 css,js 文件,并且為可替換部分預(yù)留區(qū)域。

可替換部分有,樣式,導(dǎo)航菜單、主體頁面、腳本。

因為最后是用 Flask 作為 Web 服務(wù)的,所以采用 Jinja2[3] 做為模板引擎。

代碼大致如下:

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>訓(xùn)練營311班</title>
    <link href="../static/css/bootstrap.min.css" type='text/css' rel="stylesheet">
    <link href="../static/css/dashboard.css" rel="stylesheet"> {% block head %} {% endblock %}
</head>

<body>
    <!--導(dǎo)航欄-->
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">銷售訓(xùn)練營 311班</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    {% block menu%} {% endblock %}
                </ul>
            </div>
        </div>
    </nav>
    <div class="container-fluid">
        <div class="row">
            {% block main%} {% endblock %}
        </div>
    </div>
    <script src="../static/js/bootstrap.min.js" type="text/javascript"></script>
    {% block script %} {% endblock %}
</body>
</html>

可以看出頁面采用的是 Bootstrap 框架[4],加載了 Bootstrap 必要的 Css 和 js 庫。

然后加入了頁面框架,并預(yù)留了菜單、頁面主體、定制的腳本位置。

打卡頁面

打卡頁面需要展示打卡率,最好的方式是用圖表。

首選 ECharts[5],因為 ECharts 很成熟,而且易用。

然后在 ECharts 示例[6] 中找到合適的圖表。

值得點贊的是,ECharts 示例中,提供了示例代碼,直接復(fù)制使用即可。

我們選用 柱狀圖標(biāo)簽旋轉(zhuǎn)[7]

柱狀圖標(biāo)簽旋轉(zhuǎn)

將代碼復(fù)制到頁面中。

圖表數(shù)據(jù)通過 Flask 視圖加載時提供。

部分代碼如下:

{% extends "layout.html" %} 
{% block menu %}
<li class="active"><a href="/check_rate">打卡率</a></li>
<li><a href="/memberdata">成員數(shù)據(jù)</a></li>
<li><a href="/teamleader">組長數(shù)據(jù)</a></li>
<li><a href="/sale">開單記錄</a></li>
{% endblock %} 
{% block main %}
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
    <h1 class="page-header">{{title}}</h1>
    <div class="row placeholders">
        <div class="col-xs-12 col-sm-8 col-lg-10 placeholder" style="height:500px;" id="main"></div>
        <div class="col-lg-4 col-lg-offset-4  col-sm-6 col-sm-offset-3 col-xs-8 col-xs-offset-2">
            <div id="detail">點擊圖表查看 打卡詳情</div>
        </div>
    </div>
</div>
{% endblock %} 
{% block script %}
<script src="../static/js/jquery.2.0.3.min.js" type="text/javascript"></script>
<script src="../static/js/echarts5.min.js" charset="utf-8"></script>
<script type="text/javascript">
    var app = {};
    var chartDom = document.getElementById('main');
    var myChart = echarts.init(chartDom);

    ...<省略>...

    var option = {
        title: {
            showtrue,
            left'center',
            top'top'
        },
        ...<省略>...
        dataset: {
            source: {{ data | safe }}
        },
        ...<省略>...
    }

    ...<省略>...
{% endblock %} 
  • {% extends "layout.html" %} 引入模板頁面 layout.html
  • {% block menu %}、{% block main %} 等 為替換的內(nèi)容
  • source: {{ data | safe }} 的意思是 使用視圖中的值 data 填充到這里,后面的 safe 是一個過濾器,表示替換部分不做 Html 安全字符轉(zhuǎn)化

數(shù)據(jù)縮放

這里還需要解決一個問題,就是隨著日期的增加,圖表就是很密,不好觀看,ECharts 提供一種圖表縮放工具 DataZoom,

可以通過拖動和改變大小控制數(shù)據(jù)的展示范圍,配置很簡單,加在圖表的配置中就好了,例如我的寫法是:

dataZoom: [{
    type'slider',
    start60,
    end100
}],
  • startend 表示數(shù)據(jù)范圍開始和結(jié)束的百分比,這一點特別贊

詳細(xì)數(shù)據(jù)

圖表展示后,如果想知道某一天某個組詳細(xì)的打卡數(shù)據(jù)怎么辦?

為了便于使用,利用 EChart 的事件機制,當(dāng)點擊一個柱狀圖時,顯示出詳細(xì)信息。

實現(xiàn)很簡單,就是個圖表對象加載一個事件,在事件里,使用 Ajax[8] 加載并顯示數(shù)據(jù)就好:

myChart.on('click''series'function(params{
    console.log(params);
    $.ajax({
        url"/api/teamcheckdetail",
        data: {
            team: params.seriesName,
            date: params.name
        }
    }).done(function(response{
        data = response.data;
        $("#detail").jsGrid({
            editingfalse,
            sortingfalse,
            autoloadfalse,
            data: data,
            fields: [{
                'name''name',
                'title''昵稱'
            }, {
                'name''check',
                'title''打卡'
            }]
        });
    });
});
  • 事件針對于 系列(series) 被點擊
  • /api/teamcheckdetail 為后臺數(shù)據(jù)接口(詳見 API 設(shè)計)
  • $("#detail").jsGrid() 是一個 jsGrid 做的表格,加載方法是重新炫耀一個表格

到此,最復(fù)雜的打卡頁面就搞定了,看看效果吧:

打卡率

數(shù)據(jù)列表

成員數(shù)據(jù)、組長數(shù)據(jù) 以及 開單數(shù)據(jù),都是用數(shù)據(jù)表格展示的,使用了 jsGrid[9] 框架,主要是方便易用。

在頁面上定義一個 div,并設(shè)置 id,然后用 jsGrid 方法渲染一些就可以了,和簡單。

其實在上一節(jié),我們以及看到如何渲染了,需要做的事定義后臺 API 接口,通過 Ajax 加載數(shù)據(jù)就可以了:

$("#jsGrid").jsGrid({
    height'600',
    width"100%",
    editingfalse,
    sortingfalse,
    autoloadtrue,
    controller: {
        loadDatafunction({
            var d = $.Deferred();
            $.ajax({
                url"/api/memberdata",
            }).done(function(response{
                d.resolve(response.data);
            });
            return d.promise();
        }
    },
    fields: [{'name''組'type"text"},
        {'name':'昵稱'type"text"},
        {'name':'開單'type"text"},
        {'name':'分享'type"text"},
        {'name':'打卡'type"text"},
        {'name':'提問'type"text"},
        {'name':'解答整理'type"text"},
        {'name':'積分'type"text"},
    ]
});
  • controller 里的 loadData 在頁面元素繪制完成調(diào)用
  • loadData 方法返回一個 promise[10],等數(shù)據(jù)獲取成功之后,會渲染到頁面上

那么 組長數(shù)據(jù) 和 開單數(shù)據(jù) 是類似的,就不贅述了。

數(shù)據(jù)接口

Flask 實現(xiàn)后臺接口,特別簡單,只需要再接口相應(yīng)方法前,加句注解[11] 就好了,例如 打卡率的接口:

@app.route('/')
@app.route('/check_rate')
def check_rate():
    data = dataSource.show_check_rate(rtype='dict')
    ret = [['date''1組''2組''3組''4組''5組']]
    for d in data:
        row = []
        for k in d:
            row.append(d[k])
        ret.append(row)
    return render_template('check_rate.html', title='打卡率', data=ret)
  • @app.route 是個注解,以指定 URL 路徑,由 check_rate 方法做相應(yīng)
  • dataSource 是對上一期數(shù)據(jù)處理功能的一個封裝,調(diào)用相應(yīng)方法,獲取數(shù)據(jù)
  • render_template 是 Flask 響應(yīng)頁面合成的方法,第一個參數(shù)是模板頁面,后面的命名參數(shù)是需要替換的數(shù)據(jù)

打卡率頁面的數(shù)據(jù),是合成響應(yīng)頁面時提供的,還有一些頁面需要前臺通過 Ajax 方式獲取,接口怎么寫呢?

用獲取成員數(shù)據(jù)作為例子:

@app.route('/api/memberdata')
def api_memberdata():
    data = {'data': dataSource.show_member_score(rtype='dict')}
    return jsonify(data)
  • 通過封裝的數(shù)據(jù)處理類,得到數(shù)據(jù)
  • 調(diào)用 Flask 的 jsonify 方法將數(shù)據(jù)作為 json 響應(yīng)提供給前臺

那么,其他的頁面響應(yīng)和數(shù)據(jù)響應(yīng)接口是類似的,更詳細(xì)的代碼,見代碼示例。

部署

主要的開發(fā)工作完成后,就可以部署了。

之前寫過 部署 Flask[12],用的是 uWSGI ,剛好照搬。

如果沒有 git 或者 svn 的代碼管理,就直接將復(fù)制到服務(wù)器上,安裝 Flask,就可以啟動了。

python app.py

沒有問題,配置一下 Nginx[13] 的反向代理:

server {
listen 80;
server_name stc.example.com;
access_log /var/log/nginx/access_stc.log main;
location / {
proxy_buffers 8 1024k;
proxy_buffer_size 1024k;
proxy_pass http://127.0.0.1:5000;
}
}

  • server_name 為域名,也就是通過這個地址可以訪問到系統(tǒng)的,在此之前需要申請并備案域名[14]
  • location 里的 proxy_pass 是服務(wù)器上我們的 Web 服務(wù)的地址
  • Nginx 的作用是做一個代理,將通過 stc.example.com 的訪問轉(zhuǎn)發(fā)到 真實地址上

配置完成之后,重啟一下 Nginx 服務(wù),如果沒有問題,就可以通過設(shè)置的域名訪問了。

維護

開發(fā)部署完成,還不是真的完成,還需要做運維。

以這個項目為例,運維工作主要有兩部分:

  1. 數(shù)據(jù)處理
  2. 服務(wù)器維護

只有不斷地做數(shù)據(jù)處理,才能及時更新數(shù)據(jù),這個工作對于 Web 系統(tǒng)來說,屬于支撐性的,所以沒必要讓 Web 系統(tǒng)來負(fù)責(zé)。

在 Linux 系統(tǒng)上,有個 crontab[15] 命令,用它做定時數(shù)據(jù)數(shù)據(jù),好處是開發(fā)量少,另外不會因為 Web 系統(tǒng)的問題導(dǎo)致數(shù)據(jù)處理不及時。

服務(wù)器維護,就是保證服務(wù)器不會因為異常停止工作,一般使用像 uWSGI 類的服務(wù)器都有自維護功能,如果沒有使用的話,就需要自己處理了,比如寫個監(jiān)控腳本,當(dāng)發(fā)現(xiàn)服務(wù)器不工作時,重啟服務(wù),并發(fā)送通知。

強烈建議 使用安全的 Web 服務(wù)器,特別是在生產(chǎn)環(huán)境中

總結(jié)

到此,系統(tǒng)的搭建完成了,再也不用我每天為生成報表耗費時間了,可以將更多的時間用在更重要的事情上了。

如果你認(rèn)真讀了,就會發(fā)現(xiàn),每一塊的知識技術(shù),都是很簡單的,但如何將這些簡單的點拼接起來,是需要大量的知識記錄和歷練的。

而我之所以可以這樣做,是因為在這里的長期輸出,從最基礎(chǔ)的 Web 系統(tǒng)開始,一點一點了解整個 Web 系統(tǒng)需要的基礎(chǔ),當(dāng)需要完成一個系統(tǒng)時,大部分都是來自平時的積累。

期望這篇文章對你有所啟發(fā),一切都源自持續(xù)積累,比心!

參考資料

[1]

Flask: https://mp.weixin.qq.com/s/jBom8hpmypTvdZLeZD-s_A

[2]

crontab: https://www.runoob.com/linux/linux-comm-crontab.html

[3]

Jinja2 模板引擎: https://jinja./en/3.0.x/

[4]

Bootstrap 框架: https:///

[5]

ECharts: https://echarts./zh/index.html

[6]

ECharts 示例: https://echarts./examples/zh/index.html

[7]

柱狀圖標(biāo)簽旋轉(zhuǎn): https://echarts./examples/zh/editor.html?c=bar-label-rotation

[8]

Ajax: https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX

[9]

jsGrid: http:///getting-started/

[10]

promise 對象: https://es6./#docs/promise

[11]

Python 注解: https://www.jianshu.com/p/7a644520418b

[12]

部署 Flask: https://mp.weixin.qq.com/s/b9Mmp0bSCmNVDzaExJlJ0w

[13]

Nginx: https://www./

[14]

域名備案: https://baike.baidu.com/item/%E5%9F%9F%E5%90%8D%E5%A4%87%E6%A1%88/1131453

[15]

crontab: https://www.runoob.com/linux/linux-comm-crontab.html

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    欧美不卡午夜中文字幕| 九九热精品视频在线观看| 国产成人一区二区三区久久 | 在线日本不卡一区二区| 国产女性精品一区二区三区| 日韩一区欧美二区国产| 久久精品国产99国产免费| 国产日韩在线一二三区| 老司机精品视频在线免费| 亚洲国产精品久久网午夜| 欧美日韩乱码一区二区三区| 99亚洲综合精品成人网色播 | 亚洲国产av一二三区| 亚洲中文在线男人的天堂| 中文字幕精品人妻一区| 日本精品最新字幕视频播放| 日本人妻熟女一区二区三区| 99久免费精品视频在线观| 欧美精品一区二区水蜜桃| 视频一区日韩经典中文字幕| 亚洲天堂精品1024| 亚洲天堂精品一区二区| 欧美日韩中黄片免费看| 精品国产91亚洲一区二区三区| 欧美日韩国产午夜福利| 夫妻性生活真人动作视频| 欧美不雅视频午夜福利| 国产成人精品一区二区在线看| av免费视屏在线观看| 日韩一区二区三区有码| 在线观看视频国产你懂的| 色婷婷丁香激情五月天| 国产精品免费视频久久| 日韩亚洲激情在线观看| 东京热男人的天堂社区| 91欧美日韩一区人妻少妇| 国产无摭挡又爽又色又刺激| 欧美成人免费视频午夜色| 国产免费操美女逼视频| 午夜精品一区二区三区国产| 五月激情五月天综合网|