上web課的時候老師布置的一個實驗,要求省市連動,基本要求如下:
1.用select選中一個省份。
2.省份數據傳送到服務器,服務器從數據庫中搜索對應城市信息。
3.將城市信息返回客戶,客戶用select控件進行顯示。
基本效果如下所示(頁面挺丑陋的,但是前后端數據交互的要求基本達到了):
我利用json進行數據傳輸。
所用的工具為:jQuery ajax+ python flask+mysql
想要代碼的可以直接移步github:https://github.com/HBKO/web_practice
在此過程中,可能會碰到的問題如下(下面都會給出解決辦法):
1.首先是mysql與python的中文亂碼或者無法輸入到數據庫的問題:
這里可以看我的一篇博客:http://blog.csdn.net/github_33873969/article/details/78723621
如何通過python向mysql執行sql語句並得到數據,首先要先安裝MySQLdb.
下載地址:https://pypi.python.org/pypi/MySQL-python/
下載MySQL-python-1.2.5.zip 文件之后直接解壓。進入MySQL-python-1.2.5目錄:
>>python setup.py install
- 1
執行安裝命令。
連接mysql,使用sql語句的代碼基本如下所示:
import MySQLdb
conn=MySQLdb.connect(
host='localhost', port=3306, user='root', passwd='你的密碼', db='你要連接的數據庫', charset='utf8' ) sql="你要執行的sql語句" cur=conn.cursor() #創建sql連接的游標 cur.execute(sql) #執行sql語句 result=cur.fetchone() #獲取查詢結果的第一個結果 result=cur.fetchall() #獲取查詢的全部結果 #當然,如果你要進行更新,刪除,添加的sql命令 #conn.commit() #執行更新,刪除,添加的sql命令,然后確定
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
更加詳細的連接細節,可以參考這個文檔:
https://www.cnblogs.com/fnng/p/3565912.html
二.利用jquery和ajax發送json消息:
對於ajax發送post消息非常簡單:
var data={"city":"重慶"}; $.ajax({ type: 'POST', url:"/province", data:JSON.stringify(data), //轉化字符串 contentType: 'application/json; charset=UTF-8', success:function(data){ //成功的話,得到消息 addselect(data); } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
決定發送的類型,url說明你要給你服務器上的那個url發送請求,我對應的路徑是”/province”,你要改成你自己的路徑。data數據表示一個字典類型的數據,先強制轉化為JSON類型,然后進行發送消息。
如果發送成功的話,執行后面的function函數,從服務器上獲取的數據為data.
這就是一個最簡單的POST命令的發送方法。
那么,又怎么看我們post的內容是否成功呢,這個時候就要打開你的Chrome or Firefox ,打開頁面開發者工具
看到下面頁面(記得打勾Preserve log,查看先前日志 )
可以看到我們的Request Payload的上面有我們需要傳遞的json數據,post數據成功
三.flask讀取json信息
在講flask讀取json信息,我想先介紹一下flask的一些基本概念:
首先,先說一下MVC的概念:
Model-View-Controller,中文名“模型-視圖-控制器”
首先C-controller,指的就是我們在python后台里面利用各種web框架進行數據的收集和處理.
View視圖就是我們最終將獲取的數據經過處理呈現給用戶的html頁面。
那么model又是什么呢?
下面展示一個用jinja2渲染的一個html頁面
<body> <form action="/" method="post" id="formid" > <input type="text" name="InNumber" id="InNumber" align="center" style="height: 50px; width: 400px; font-size: 40px" placeholder="20 30 40 .."> <br> <input type="button" name="btn1" value="進行排序" align="center" onclick="sendmessage()"> <br> </form> <p>{{result}} </p>> <input type="button" value="省市聯動" align="center" onclick="changepage()"> </body>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
下面的{{result}}就是一個模型,這個模型包括了從服務器傳回來的數據.
在里面,model就是dict類型的數據:”result”:”….”
這是不是很想我們的json。沒錯的,在我們前后端交互的MVC模型中,M表示的就是我們交互傳遞的json數據。
好了,回到正題,服務器端獲取json的方式有這么幾種
request.form request.args request.data request.get_json()
- 1
- 2
- 3
- 4
我們依次打印出來看結果:
ImmutableMultiDict([])
ImmutableMultiDict([])
{"city":"浙江"} {u'city': u'\u6d59\u6c5f'}
- 1
- 2
- 3
- 4
第三個結果看似是我們想要,我們打印出它的類型再看看
<type 'str'>
- 1
它是一個str類型的數據,不是我們想要的
第四個結果是一個dict類型的數據,我們獲取一下值,看是不是我們想要的
print request.get_json()['city']
- 1
浙江
- 1
成功獲取了我們發送的消息。
OK,我們成功得到了我們的數據,接下來就進行數據庫搜索,最后發送消息就行了。
但如何往瀏覽器發送消息呢?如下代碼:
@app.route('/province',methods=['POST','GET']) def province(): if request.method=='POST': rev=request.get_json()['city'] result=selcity(rev) return result else: return render_template('province.html')
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
直接把你的結果return就完啦,是不是很簡單呀。
這就完成通過ajax和flask進行數據交互的一個過程,瀏覽器怎么處理數據,那就是view要做的事嘍。
接下來,就是服務器端代碼嘍:
#!/usr/bin/env python #encoding=utf-8 from flask import Flask from flask import render_template from flask import request from flask import url_for import MySQLdb import re import sys import types app=Flask(__name__) reload(sys) sys.setdefaultencoding("utf-8") conn=MySQLdb.connect( host='localhost', port=3306, user='root', passwd='a821200725', db='webjob', charset='utf8' ) #sys.setdefaultencoding('utf-8') @app.route('/', methods=['POST','GET']) def index(): if request.method == 'POST': InNumber=request.form['InNumber'] InNumber=numsort(InNumber) return render_template('index.html',result=InNumber) else: return render_template('index.html') @app.route('/province',methods=['POST','GET']) def province(): if request.method=='POST': rev=request.get_json()['city'] result=selcity(rev) return result else: return render_template('province.html') def numsort(number): print number # tmp=number.split(' *') tmp=re.split("\s+",number) print tmp for i in range(len(tmp)): tmp[i]=int(tmp[i]) print tmp tmp.sort() res="" for i in tmp: res+=(str(i)+" ") return res def selcity(city): sql="select litcity from Bigcity where city='"+city+"'" cur=conn.cursor() cur.execute(sql) result=cur.fetchone() results=result[0] # results=results.decode("unicode-escape") return results if __name__=='__main__': app.run(debug=True)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
可以看到flask在創建簡單的web應用的時候確實很輕便,一個app.run就完了。
這里要注意兩個地方:
一個是:
@app.route('/', methods=['POST','GET']) def index():
- 1
- 2
這個是裝飾器,用於綁定路由到def index這個函數。
也就是這時候你的url為ip+/的時候,服務器執行的就是index這個函數,要返回模版頁面就只要:
return render_template(‘頁面’)就好啦。
但你如果在前端加載服務器的靜態文件,如:CSS,JS,IMG。
就要在前端寫上:
{{url_for('static', filename='style.css')}}
- 1
當然你的靜態文件要存在服務器的static文件夾中,
具體的頁面代碼例子如下:
<link rel="icon" href="{{ url_for('static', filename='favicon.ico')}}" type="image/x-icon">
- 1
另外一個就是:
if __name__=='__main__':
- 1
這個保證了,如果你直接執行的這個py文件,就會執行if里面語句。
但是你如果把這個py文件當成模塊引入,就不會執行if里面語句。實際上,這時候
__name__='你的py文件名'