摘要:本文將爲你們帶來基於Flask框架和JQuery實現管理平臺網站的開發功能。
你要開發網站? 嗯。。css
會Flask嗎? 什麼東西,沒聽過。。。html
會JQuery嗎? 是python的庫嗎 ?python
那你會什麼? 我會F12打開網站jquery
好吧,那咱們來寫個簡單的表格管理平臺。web
基於Flask框架和JQuery實現管理平臺網站的開發功能,我代碼編寫用了2天的時間 ,從零開始寫;又對具體實現流程,本身斷斷續續地整理總結了近半個月。從自我感受來講,整個過程和結果的實現都讓我很滿意。ajax
(1)Django:簡單來講就是重武器,是最全能的開發框架,你想要的功能它都有;可是比較繁重,適合企業級的web開發;sql
(2)Flask:屬於web開發微框架,小巧靈活,相關的第三方庫豐富,適合開發小型web;數據庫
(3)Tornado:天生異步,性能強悍,可是框架提供的功能少,須要開發者本身實現;編程
所以,本文代碼實現主要是基於Flask實現的。json
幾乎全部的編程都是基於「hello world」實現的,所以也大體講下helloworld涉及的內容。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world(): return "Hello world!"
if name == '__main__':
app.run()
先聲明一個Flask框架的對象,而後定義路由'/',即URL地址爲 http://127.0.0.1:5000/;若是定義路徑爲‘/new’,那對應的訪問地址須要改成http://127.0.0.1:5000/new。另外,@app.route是個裝飾器。
app.run(debug=True,host="x.x.x.x",port="1234")
經過對app.run()方法的參數定義,分別實現了調試功能,訪問URL變動爲 http://x.x.x.x:1234
這裏調試功能仍是很好用的,不但能夠幫助開發者從新加載網頁,並且會打印詳細的錯誤信息,協助定位。
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world(): return render_template('test.html') if name == '__main__':
app.run()
只須要導入render_template庫,而且在函數返回時改爲對應的方法便可。
不過 這 裏要 注意,test.html必須保存在工程目錄與下template文件下,不然會報錯。(這是由於render_template方法定義時默認寫了template路徑 )
web數據交互離不開後臺數據庫的管理,本章節重點解釋python自帶的sqlite3數據庫。相比較於其餘「正規」的數據庫,如mongo、solr、MySQL等,sqlite3至關簡單,屬於輕量級的數據庫。
一、sqlite3數據庫的安裝和建立
用pip命令能夠下載安裝sqlite3數據庫
建立數據庫:
con = sqlite3.connect('material.db')
若是有數據庫material.db,則進行鏈接數據庫的操做;若是沒有此數據庫,則先建立數據庫再進行鏈接;
二、建立數據表
label = ['ID','網絡IP','地址','責任人','聯繫方式']
content = ['1','10.10.10.10','杭州濱江','鵬哥','123456']
def create():
sql = 'create table {0} ({1},{2},{3},{4},{5})'.format(tablename,label[0],label[1],label[2],label[3],label[4]) result = cur.execute(sql) con.commit() return True if result else False
簡單描述爲:create table 表名 (各字段名1,各字段名2……)
當前對數據表的字段未進行輸入類型及長度的限制,好比須要規則ID爲必填項,而且爲整形,長度在10個字節內,則須要修改成
sql = 'create table matrial_table ("ID" int[10] primary key not null )'
同理,其餘字段也能夠相同的方式進行類型、長度的限制。
注意:在執行cur.execute()後,要記得con.commit()進行數據庫提交,不然數據並不會真正寫入數據庫中。
def insert():
sql = 'insert into {0} ({1},{2},{3},{4},{5}) values({6},"{7}","{8}","{9}","{10}")'.format(tablename,label[0],label[1], label[2],label[3],label[4],content[0],content[1],content[2],content[3],content[4]) result = cur.execute(sql) con.commit() return True if result else False
簡單描述爲:insert into 表名 (各字段名1,各字段名2……) values(數值1,數值2……)
這 裏要注意,」{7}「 是有加雙引號的,爲何呢?由於」{7}「對應的是網絡IP,是個字符串,所以須要加 雙引號,不然會報錯。
def query():
sql = 'select * from {0}'.format(tablename) result = cur.execute(sql) return list(result)
簡單描述爲:select XX,XX from 表名 where 字段名1="數值1"
若是生成了db數據庫,如何查看呢?能夠下載一個SQLite Expert,打開後就能夠很直觀地進行數據庫查看,而且能夠經過圖形化按鈕進行 數據表的增刪改查。
一、Flask框架方法編寫
前面已經講過 Flask如何調用html模板,所以咱們直接展現上圖對應的flask框架方法的代碼
import sqlite3
app = Flask(__name__)
con = sqlite3.connect('material.db',check_same_thread=False)
@app.route('/')
def Material_Mangement():
# 獲取數據庫material_table表的內容 cur = con.cursor() sql = 'select * from {0}'.format("material_table") cur.execute(sql) content = cur.fetchall() # 獲取數據庫表的表頭 labels = [tuple[0] for tuple in cur.description] return render_template('test.html',content=content,labels=labels) if __name__ == '__main__': app.run(debug=True)
動態路由、sqlite3數據庫操做、調試模式的設置,這些知識請參考以前的博客。但有2個知識點,我想再提下:
(1)若是在數據庫鏈接時,不添加check_same_thread=False參數,則
數據庫鏈接會報錯:sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id XX。
這是由於sqlite3數據庫被多線程訪問致使衝突,所以這裏要注意下。
(2)獲取數據庫表頭:labels = [tuple[0] for tuple in cur.description]
二、Html文件(僅展現表格內容)
<!doctype html>
<html>
<head>
<!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <title>物料管理平臺</title>
</head>
<body>
<div>
<div class="col-md-6 col-sm-12 col-xs-12"> <div class="panel panel-default"> <div> <h3>表格管理平臺</h3> </div> <div> <div> <table class="table table-striped table-bordered table-hover"> <thead> <tr> {% for i in labels %} <td>{{ i }}</td> {% endfor %} </tr> </thead> <tbody> {% for i in content %} <tr> {% for j in i %} <td>{{ j }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body>
</html>
對應的效果是這樣的:
由於一開始接觸flask時,我只調試過html,可是根本沒具體接觸過html怎麼寫。所以上述這段代碼是參考於大神的代碼(https://blog.csdn.net/a199904...)。
熟悉這段代碼後,我以爲有幾塊內容是和我要實現的代碼有關的。
(1)title 標題修改
(2)表格的長寬大小:<div class="col-md-6 col-sm-12 col-xs-12"> 。 col-xs-和col-sm- 和col-md-*(col-xs表示超小屏幕,col-md-中等屏幕,col-sm-小屏幕)主要是用來適應不一樣屏幕的表格展現。所以須要自適應調整對應的數值。
(3)設置表格的ID:<table class="table table-striped table-bordered table-hover",id="test">。這裏其實不設置id也是能夠的,可是後續我要對錶格進行編輯時,加上id會方便我定位表格,方法是:tab = document.getElementById("test")
三、Html文件(添加編輯、提交按鈕)
根據上述要修改的點,我從新修改了html內容,新的html代碼以下:
<!doctype html>
<html>
<head>
<!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <title>表格管理平臺</title>
</head>
<body>
<div>
<div class="col-md-12 col-sm-12 col-xs-12"> <div class="panel panel-default"> <div> <h3>表格管理平臺</h3> </div> <div> <div> <table class="table table-striped table-bordered table-hover"> <thead> <tr> {% for i in labels %} <td>{{ i }}</td> {% endfor %} </tr> </thead> <tbody> {% for i in content %} <tr> {% for j in i %} <td>{{ j }}</td> {% endfor %} <td><input type="button" value="編輯"></td> <td><input type="submit" value="提交"></td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script> (function(){
$('input[type="button"]').on('click', function(){ var $this = $(this), edit_status = $this.attr('edit_status'), status_value = edit_status && 1 == edit_status ? 0 : 1, $td_arr = $this.parent().prevAll('td'); $this.val(1 == status_value ? '完成' : '編輯').attr('edit_status', status_value); $.each($td_arr, function(){ var $td = $(this); if(1 == status_value) { $td.html('<input type="text" value="'+$td.html()+'">'); } else if(0 == status_value){ $td.html($td.find('input[type=text]').val()); } }); }); })(); </script>
</body>
</html>
相比於第 2步時的html文件,此次我主要添加了2塊內容:
(1)添加編輯、提交按鈕:
<td><input type="button" value="編輯"></td> <td><input type="submit" value="提交"></td>
將這兩行代碼放在表格每行最後,就會生成相應的按鈕
(2)編輯功能的實現:
編輯按鈕對應的function是基於JQuery寫的,
固然這 段代碼我也是參考另外一位大神的(https://blog.csdn.net/luo2012...),由於當前我對JQuery徹底一無所知。
可是在熟悉代碼後,我根據本身對代碼的理解進行了註釋。
<script> (function(){ <!--定義屬因而 button的按鈕在點擊後,產生下面的function功能--> $('input[type="button"]').on('click', function(){ <!--獲取當前事件,並進行當前按鈕的狀態,若是是編輯狀態,就進行將每一個單元格設置成可輸入狀態-->
var $this = $(this), edit_status = $this.attr('edit_status'), status_value = edit_status && 1 == edit_status ? 0 : 1, $td_arr = $this.parent().prevAll('td'); $this.val(1 == status_value ? '完成' : '編輯').attr('edit_status', status_value); <!--若是單元格是可編輯狀態,獲取每列元素的值,並在最後html表格上進行展現--> $.each($td_arr, function(){ var $td = $(this); if(1 == status_value) { $td.html('<input type="text" value="'+$td.html()+'">'); <!--若是按鈕狀態是完成狀態,直接展現單元內的值--> } else if(0 == status_value){ $td.html($td.find('input[type=text]').val()); } }); }); })(); </script>
細心的同窗會發現,我在點擊」提交「按鈕時,什麼都沒 發生。是的,」提交「功能,我將在下一個章節中進行介紹。
一、提交功能的實現,對我來講,最難的是html對前臺數據的傳輸。所以,我就參考着編輯功能,本身一 點點寫。如下是示例代碼:
(1)HTML文件編寫前臺界面提交功能
<script> (function(){ <!--定義屬性是submit的按鈕在點擊後,產生下面的function功能--> $('input[type="submit"]').on('click', function(){ <!--獲取當前行的id -->
var td = event.srcElement.parentElement; var rownum = td.parentElement.rowIndex; <!--獲取html表格元素 --> var tab = document.getElementById("test"); <!--將每一個單元格元素進行取值,並以字典形式傳給後臺 --> var data = { "ID":tab.rows[rownum].cells[0].innerHTML, "網絡IP":tab.rows[rownum].cells[1].innerHTML, "地址":tab.rows[rownum].cells[2].innerHTML, "責任人":tab.rows[rownum].cells[3].innerHTML, "聯繫方式":tab.rows[rownum].cells[4].innerHTML, }; alert("提交成功!") $.ajax({ type: "get", url: "/edit", data: data, dataType: "json" }); }); })();
(2)後臺對提交後的數據進行讀取,並寫數據庫
@app.route('/edit', methods=['get'])
def edit():
label = ['ID', '網絡IP', '地址', '責任人', '聯繫方式'] content = [request.args.get(i) for i in label] print(content) sql = 'update {0} set {1}="{6}",{2}="{7}",{3}="{8}",{4}="{9}" where {5}={10}'.format('material_table', label[1], label[2], label[3],label[4],label[0],content[1],content[2],content[3],content[4],content[0]) cur = con.cursor() cur.execute(sql) con.commit() return "數據寫入成功!"
在實現「提交」功能時,我主要遇到了如下幾個 坑:
(1)html代碼寫完後,發現程序報錯,提示$.ajax is not a function。我去,我看其餘大神的數據交互也是這麼寫的呀,爲何我這不行?
查看網上的帖子,都是說未定義或者和其餘庫有衝突,最後我本身發現,是由於我沒有聲明是JQuery。須要在script前面加上一行代碼:
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
我理解這行代碼的意思是聲明下面要JQuery庫,而不是其餘JS庫。(可能理解有誤)
最後加上這行代碼後,問題成功解決!
(2)獲取當前行號
一開始在獲取行號,怎麼獲取不到,並且不知道要怎麼調試,在同事的指導下,才學會經過alert(td.innerHTML)來查看獲取的當前行內容是什麼。
最初從網上 查到獲取當前行的寫法是:
var td = event.parentElement; var rownum = td.parentElement.rowIndex;
經過alert調試,發現點擊提交根本沒有反應;又改爲
var td = event.srcElement; var rownum = td.parentElement.rowIndex;
結果是獲取不到任何內容
就這麼個小問題就花費了我近2個小時的時間去不停地查資料,嘗試編寫。最後想說的是,若是對html不熟悉,仍是應該找個大神帶帶本身的。
最後在別人的協助下,實現了獲取當前行的功能:
(3)獲取每一個表格裏的 內容
tab.rows[0].cells[0].innerHTML
在獲取單元格內數據時,最驗證的是我獲取不到tab,即表格元素。由於我原先沒有在表格元素里加id,即
網上找了不少方法都無法實現,最後老老實實地加上 id="test"
講道理,html裏的這 20行代碼是我搞這個表格管理平臺時,花費最大精力的。至此,表格管理平臺的功能基本成行 !
以上功能只實現了對現有數據的編輯保存功能,可是若是用戶想要新增數據,怎麼辦?我當時第一個想法是讓用戶本身去改數據庫,哈哈。還要我去寫新增功能,要累死了,不想寫。
下面是關於新增功能的介紹和示例代碼。
一、如何添加「新增」按鈕
<td><input type="button" value="新增" id="create"></td>
若是前面 的html能看懂了,這行是不難理解的。
二、點擊新增按鈕後,如何動態增長表格行、列
<script> (function () {
$('input[id="create"]').on('click', function(){ var editTable=document.getElementById("tbody"); var tr=document.createElement("tr"); var td1=document.createElement("td"); td1.innerHTML=""; tr.appendChild(td1); editTable.appendChild(tr);
首先定義tr元素,而後在tr元素中再追加td元素。若是表格裏有多列數據,那隻須要重複td1的寫法,進行復制粘貼就能夠了。
另外,當前td.innerTHML是設置爲空,若是要將該單元格直接設置爲編輯狀態,則修改爲 :
td1.innerHTML="input[type=text] /";
三、如何動態添加「編輯」、「提交」按鈕,下面以「編輯」爲例
var td9 = document.createElement("td") var myedit =document.createElement("input");
myedit.type = "button";
myedit.value = "編輯" myedit.id = "edit" td9.appendChild(myedit)
添加方式和添加文本框方式是同樣的,只是須要注意元素類型是Input,而且要補充下元素的type/value/id。
四、如何對動態添加的按鈕進行事件綁定,下面以提交功能爲例
$('input[id="submit"]').on('click', function(){
alert("test")
}
關於動態添加的按鈕進行事件綁定有不少帖子,有用Live方法的,有用$(document).on('click','.edit',function()方法的,其實不用這麼麻煩,和正常的「提交」寫法是徹底同樣的。
五、獲取當前新增行內的數據,進行提交。
var tab = document.getElementById("test"); var rownum = td1.parentElement.rowIndex;
$('input[id="submit"]').on('click', function(){ var data = { "ID":tab.rows[rownum].cells[0].innerHTML, }; alert("新增成功!") $.ajax({ type: "get", url: "/create", data: data, dataType: "json" }); });
這段代碼和提交功能的實現是同樣的,大同小異。
本文分享自華爲雲社區《【Python成長之路】從 零作網站開發 -- 基於Flask和JQuery,實現表格管理平臺》,原文做者: 鵬哥賊優秀 。