時(shí)間:2022-08-29 02:36:01 | 來源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2022-08-29 02:36:01 來源:網(wǎng)站運(yùn)營(yíng)
python在網(wǎng)絡(luò)方面的應(yīng)用非常廣泛,這里我們關(guān)注一下網(wǎng)站服務(wù)器及web開發(fā)部分。python幾行代碼就可以搭建一個(gè)web服務(wù)器,然后使用python語言來開發(fā)后臺(tái)服務(wù)。之前的文章我對(duì)web服務(wù)做了較為詳細(xì)的介紹,這個(gè)服務(wù)主要包括http的各種類型請(qǐng)求,如get、post等常規(guī)請(qǐng)求。對(duì)于web開發(fā),不同頁面之間的跳轉(zhuǎn)、數(shù)據(jù)傳輸通信、網(wǎng)頁存儲(chǔ)、緩存等是基礎(chǔ)知識(shí),如果采用原生python來寫估計(jì)難度還是很大的,所以感謝前人栽樹,有了一些成熟的框架模塊,我們?cè)賮硎褂脮r(shí)就非常方便。當(dāng)然至于python用于web服務(wù)的性能如何,這里我們不做討論。在web開發(fā)框架部分,較為知名的包括django、flask等框架。from flask import Flask #導(dǎo)入Flask類app=Flask(__name__) #實(shí)例化并命名為app實(shí)例if __name__=="__main__": app.run(port=2020,host="127.0.0.1",debug=True) #調(diào)用run方法,設(shè)定端口號(hào),啟動(dòng)服務(wù)
執(zhí)行該文件,在終端就有如下提示:from flask import Flaskapp=Flask(__name__)@app.route('/')def index(): return 'welcome to my webpage!'if __name__=="__main__": app.run(port=2020,host="127.0.0.1",debug=True)
代碼中使用了裝飾器來制定路由url,具體寫法如下:@app.route('/') #調(diào)用route路由方法,括號(hào)里給定參數(shù),/符號(hào)默認(rèn)為首頁@app.route('/home/user') #調(diào)用route路由方法,/home/user定位到訪問user方法頁面
在定制了路由url后,還需要給定一個(gè)實(shí)現(xiàn)方法,使用python定義函數(shù)的方式來實(shí)現(xiàn),如上index函數(shù),返回一個(gè)字符串welcome to my webpage。也就是當(dāng)路由url定位到首頁時(shí),就調(diào)用這個(gè)index函數(shù),此時(shí)就會(huì)在瀏覽器上輸出這個(gè)字符串內(nèi)容。@app.route('/')def index(): return '<h3>welcome to my webpage!</h3><hr><p style="color:red">輸出語句測(cè)試</p>'
再重新運(yùn)行py文件,瀏覽器刷新一下就顯示為:from flask import Flask,render_template #導(dǎo)入render_template模塊app=Flask(__name__)@app.route('/')def index(): return render_template("index.html") #調(diào)用render_template函數(shù),傳入html文件參數(shù)if __name__=="__main__": app.run(port=2020,host="127.0.0.1",debug=True)
如果這樣運(yùn)行,pycharm終端會(huì)提示報(bào)錯(cuò),因?yàn)檎也坏絠ndex.html文件。flask框架在使用這個(gè)模板函數(shù)時(shí),默認(rèn)去尋找項(xiàng)目文件夾下的templates文件夾里的html文件。因此我們需要先新建一個(gè)templates文件夾,然后在里面新建一個(gè)html文件,項(xiàng)目結(jié)構(gòu)及內(nèi)容參考如下:{% python語句 %}{{ 變量 }}
我們繼續(xù)將上述案例代碼修改一下,來測(cè)試一下數(shù)據(jù)傳輸效果:from flask import Flask,render_templateapp=Flask(__name__)@app.route('/')def index(): msg="my name is caojianhua, China up!" return render_template("index.html",data=msg) #加入變量傳遞if __name__=="__main__": app.run(port=2020,host="127.0.0.1",debug=True)
然后在index.html中修改:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>welcome to 2020</title></head><body> welcome to my webpage <hr> <p>這是采用render_template模板方法獲得的內(nèi)容:</p> <br> {{data}} #顯示出傳遞過來的變量?jī)?nèi)容</body></html>
保存后重新啟動(dòng)web服務(wù),然后瀏覽器上刷新一下(默認(rèn)瀏覽器地址欄還是127.0.0.1:2020訪問首頁):<img src="{{ url_for('static',filename='img/main.jpg')}}" alt="">
使用jinjia2模板的url_for路由函數(shù),指定為static目錄下,filename指向具體圖片。from flask import Flask,render_templateapp=Flask(__name__)@app.route('/')def index(): msg="my name is caojianhua, China up!" return render_template("index.html",data=msg)@app.route('/news') #增加一個(gè)news頁面def newspage(): newsContent="全國(guó)上下一心支持武漢,武漢加油!" return render_template("news.html",data=newsContent)app.route('/product') #增加一個(gè)product頁面def productpage(): return render_template("product.html") if __name__=="__main__": app.run(port=2020,host="127.0.0.1",debug=True)
然后根據(jù)路由設(shè)定,在templates文件夾下新增兩個(gè)網(wǎng)頁文件,news.html和project.html。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>news</title></head><body><p>今日新聞</p><p>2020年1月28日0-24時(shí),浙江省報(bào)告新型冠狀病毒感染的肺炎新增確診病例123例,新增重癥病例11例,新增出院病例2例。</p><hr><p style="color:red">{{data}}</p></body></html>
接下來重啟一下main.py文件,在瀏覽器地址欄輸入: 127.0.0.1:2020/news,即可獲得如下頁面:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>news</title></head><body><p>今日新聞</p><p>2020年1月28日0-24時(shí),浙江省報(bào)告新型冠狀病毒感染的肺炎新增確診病例123例,新增重癥病例11例,新增出院病例2例。</p><hr><p style="color:red">{{data}}</p><p><a href="/ ">回到首頁</a></p> #回首頁超鏈接<p> <a href="{{ url_for('productpage') }}">去看產(chǎn)品頁</a></p> #產(chǎn)品頁鏈接</body></html>
代碼中url_for函數(shù)給定參數(shù)是路由頁面的函數(shù)名,如本例中的產(chǎn)品頁,main.py函數(shù)中路由為/product,但函數(shù)名為productpage,這里a超鏈接需要給定函數(shù)名即projectpage,<a href="{{ url_for('productpage') }} " ?;厥醉摮溄又苯咏o/即可,<a href="/">。也可以直接使用路徑方式,如/product,就是尋找main.py文件的product路由名,這也是指向了productpage函數(shù)。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>welcome to 2020</title></head><body> welcome to my webpage<ul> <li><a href="/news">查看新聞</a></li> <li><a href="/product">查看產(chǎn)品</a></li></ul> <hr> <p>這是采用render_template模板方法獲得的內(nèi)容:</p> <br> {{data}}</body></html>
首頁效果如下:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>welcome to 2020</title></head><body> welcome to my webpage<ul> <li><a href="/news">查看新聞</a></li> <li><a href="{{ url_for('productpage',a=50) }}">查看產(chǎn)品</a></li> #注意超鏈接帶參數(shù)a傳遞</ul> <hr> <p>這是采用render_template模板方法獲得的內(nèi)容:</p> <br> {{data}}</body></html>
因?yàn)橐D(zhuǎn)到product裝飾器位置,就需要將其修改一下如下:@app.route('/product/<a>',methods=['GET'])def productpage(a): return render_template("product.html",data=a)
此時(shí)在product.html中增加一行讀取這個(gè)data的值:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>product</title></head><body>傳遞過來的值為{{data}}<p>庫克表示,他不會(huì)就5G方面的未來蘋果產(chǎn)品發(fā)表評(píng)論,但表示5G處于“在全球范圍內(nèi)進(jìn)行部署的早期階段”。蘋果對(duì)其現(xiàn)有的iPhone產(chǎn)品線“感到驕傲”</p></body></html>
此時(shí)從首頁點(diǎn)擊查看產(chǎn)品鏈接時(shí),就可以順利將參數(shù)傳遞到product.html頁面了。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>welcome to 2020</title> <style> .rr{float:left;width:50%;}</style></head><body><div style="width:600px;height:30px"> <div class="rr"> welcome to my webpage </div> <div class="rr"> {% if data != '' %} #如果存在data變量的值,就顯示用戶姓名,以及注銷鏈接 <a href="#">{{ data}}</a> <a href="#">注銷</a> {% else %} #否則就顯示登錄與注冊(cè)鏈接 <a href="#">登陸</a> <a href="#">注冊(cè)</a> {% endif %} </div> <div style="clear:both;"></div></div><img src="{{ url_for('static',filename='img/main.jpg')}}" alt=""><hr><ul> <li><a href="/news">查看新聞</a></li> <li><a href="/product">查看產(chǎn)品</a></li></ul></body></html>
當(dāng)點(diǎn)擊登錄鏈接時(shí),路由指向main.py中的login,該函數(shù)直接跳轉(zhuǎn)到login.html頁面里。在main.py中這部分代碼如下:@app.route('/login')def loginpage(): return render_template("login.html")
在login.html里設(shè)計(jì)一個(gè)表單輸入,注意form的action指向路由:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>userlogin</title></head><body><center> <h3>用戶登錄頁面</h3> <div> <form action="/loginProcess" method="post"> 用戶名: <input type="text" name="nm"><br> 用戶密碼: <input type="password" name="pwd"> <br> <input type="submit" name="submit" value="登錄"> </form> </div></center></body></html>
form中的action路由指向?yàn)閘oginProcess,此時(shí)我們?cè)趍ain.py中增加這個(gè)路由裝飾器及對(duì)應(yīng)的函數(shù),同時(shí)由于涉及表單數(shù)據(jù)的接收,此時(shí)就需要導(dǎo)入flask的request包,調(diào)用其form屬性,具體用法如下:data=request.form #data為一個(gè)接收表單的數(shù)組對(duì)象或者 name=request.form['nm'] #接收到用戶名文本框的輸入并賦值給name變量
此時(shí)loginProcess路由代碼如下:@app.route('/loginProcess',methods=['POST','GET'])def loginProcesspage(): if request.method=='POST': nm=request.form['nm'] #獲取姓名文本框的輸入值 pwd=request.form['pwd'] #獲取密碼框的輸入值 if nm=='cao' and pwd=='123': return render_template("index.html",data=nm) #使用跳轉(zhuǎn)html頁面路由 else: return 'the username or userpwd does not match!'
這里的當(dāng)輸入值滿足條件時(shí),使用了render_template來進(jìn)行頁面渲染,實(shí)際上是不合適的。不過為了說明表單輸入的處理方式,我們先這樣運(yùn)行,如此就基本實(shí)現(xiàn)了表單輸入的接收。return redirect(url_for('index'))
還是使用到url_for方法,尋找到對(duì)應(yīng)的路由處理函數(shù)。不過不像rendertemplate可以傳遞參數(shù),redirect默認(rèn)參數(shù)里沒有傳值功能,因此如這種用戶注冊(cè),需要使用一下會(huì)話session緩存技術(shù)。也就是將正確的用戶名保存到session數(shù)組變量中。使用的時(shí)候先從flask庫中導(dǎo)入session模塊,同時(shí)為了保證安全,還需要給定一個(gè)app.secret_key: app.secret_key='any random string' #這里我們直接給定一個(gè)密鑰
然后在剛才登錄loginProcess代碼中增加一個(gè)session會(huì)話存儲(chǔ)功能:@app.route('/loginProcess',methods=['POST','GET'])def loginProcesspage(): if request.method=='POST': nm=request.form['nm'] pwd=request.form['pwd'] if nm=='cao' and pwd=='123': session['username']=nm #使用session存儲(chǔ)方式,session默認(rèn)為數(shù)組,給定key和value即可 return redirect(url_for('index')) #重定向跳轉(zhuǎn)到首頁 else: return 'the username or userpwd does not match!'
接下來在首頁index.html頁面中修改一下:<div class="rr"> {% if session['username'] == 'cao' %} #如果session中用戶名為cao,以及注銷鏈接 <a href="#">{{ session['username']}}</a> <a href="#">注銷</a>
這樣就完整實(shí)現(xiàn)了用戶的登錄,當(dāng)然這里的用戶目前只限定了一個(gè)人名cao。如下為用戶登錄界面以及登錄后首頁的效果。from flask import gg.name='cao'
在當(dāng)前頁面請(qǐng)求中就可以直接使用g的值了。@app.context_processordef common(): isLogin=False return isLogin
這樣代碼中的isLogin變量就會(huì)在項(xiàng)目業(yè)務(wù)中通用。class dbUtils: def __init__(self, dbName): # 連接數(shù)據(jù)庫 import sqlite3 self.conn = sqlite3.connect(dbName) def db_action(self, sql, actionType=0): # 進(jìn)行相關(guān)業(yè)務(wù)操作 try: res = self.conn.execute(sql) if actionType == 1: # 當(dāng)操作類型為1時(shí)代表為查詢業(yè)務(wù),返回查詢列表 return res.fetchall() else: # 當(dāng)操作類型不為1時(shí)代表為新增、刪除或更新業(yè)務(wù),返回邏輯值 return True except ValueError as e: print(e) def close(self): # 關(guān)閉數(shù)據(jù)庫 self.conn.commit() self.conn.close()#1.創(chuàng)建數(shù)據(jù)庫db=dbUtils('web2020.db')#2.創(chuàng)建新聞表sql='create table news (newsid int, content text, author text)'if db.db_action(sql,0)==True: print("創(chuàng)建新聞表成功!")else: print("try again1")#3.新增新聞sql= "insert into news values(1,'武漢疫情非常嚴(yán)重,口罩等急需物品短缺','cao')," / "(2,'全國(guó)人民都給武漢加油,疫情肯定會(huì)控制住','cao')"if db.db_action(sql,0)==True: print("新增新聞表成功!")else: print("try again1")db.close()
執(zhí)行后,就完成了新聞表的創(chuàng)建,同時(shí)新增了兩條新聞。@app.route('/news')def newspage(): import dbutil #導(dǎo)入dbutil模塊,就是上面這個(gè)文件 db=dbutil.dbUtils('web2020.db') #鏈接web2020數(shù)據(jù)庫 sql='select * from news' #組裝查詢sql語句 newslist=db.db_action(sql,1) #查詢處理并返回列表 db.close() #關(guān)閉數(shù)據(jù)庫 return render_template("news.html",data=newslist) #將數(shù)據(jù)傳遞到news.html頁面中
然后在news.html頁面中使用jinjia2模板中的語法來讀取兩條新聞內(nèi)容:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>news</title></head><body><p>今日新聞</p>{% for item in data %} #采用循環(huán)來讀取列表中的內(nèi)容 <p style="color:red">{{item}}</p>{% endfor %}<hr><p><a href="/ ">回到首頁</a></p><p> <a href="{{ url_for('productpage',a=50) }}">去看產(chǎn)品頁</a></p></body></html>
運(yùn)行結(jié)果如下:from flask import Blueprint, render_template, session, url_for,requestfrom werkzeug.utils import redirectuser=Blueprint('user',__name__) #藍(lán)圖使用方法,參數(shù)里給定文件名,還可以給定url前綴@user.route('/login') #使用user的路由配置def loginpage(): return render_template("login.html")@user.route('/loginProcess',methods=['POST','GET']) #使用user 的路由配置def loginProcesspage(): if request.method=='POST': nm=request.form['nm'] pwd=request.form['pwd'] if nm=='cao' and pwd=='123': session['username']=nm print(session['username']) return redirect(url_for('index')) else: return 'the username or userpwd does not match!'
可以看到其中主要的語句為:user=Blueprint('user',__name__) #藍(lán)圖使用方法,參數(shù)里給定文件名,還可以給定url前綴
將user.py文件名user作為藍(lán)圖來使用傳入Blueprint方法中,另外如果需要還可以在這里加入url前綴限定:url_prefix=‘/user'。整個(gè)參數(shù)包括有很多,這里截圖如下:from flask import Blueprint, render_templatenews=Blueprint('news',__name__) #news藍(lán)圖@news.route('/news')def newspage(): import dbutil db=dbutil.dbUtils('web2020.db') sql='select * from news' newslist=db.db_action(sql,1) return render_template("news.html",data=newslist)@news.route('/news/edit')def newsEditpage(): return '/news/edit'
如下為product.py藍(lán)圖:from flask import Blueprint, render_templateproduct=Blueprint('product',__name__)@product.route('/product')def productpage(): return render_template("product.html")
這樣就將各個(gè)業(yè)務(wù)單獨(dú)分開處理了,最后我們?cè)趍ain.py主路由文件中將上述的文件采用藍(lán)圖注冊(cè)方式導(dǎo)入即可。from flask import Flask, render_template, url_for, request, redirect, sessionfrom news import news #導(dǎo)入news藍(lán)圖from user import user #導(dǎo)入user藍(lán)圖from product import product #導(dǎo)入product藍(lán)圖app=Flask(__name__)app.secret_key='any random string'urls=[news,user,product] #將三個(gè)路由構(gòu)建數(shù)組for url in urls: app.register_blueprint(url) #將三個(gè)路由均實(shí)現(xiàn)藍(lán)圖注冊(cè)到主app應(yīng)用上@app.route('/')def index(): userinfo='' return render_template("index.html",data=userinfo)if __name__=="__main__": print(app.url_map) #打印url結(jié)構(gòu)圖 app.run(port=2020,host="127.0.0.1",debug=True)
保存好幾個(gè)文件后,從main.py中執(zhí)行啟動(dòng)服務(wù),在瀏覽器地址欄里可以順利瀏覽本案例實(shí)現(xiàn)的網(wǎng)站,這已經(jīng)測(cè)試正常通過。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>{% block title %}Title {% endblock %} </title></head><body> {% block header %} <div>header</div> {% endblock %} {% block container %} <div>content</div> {% endblock %} {% block footer %} <div>made by Dr.Cao</div> {% endblock %}</body></html>
如代碼中,使用了{(lán)% block header %}--{% endblock %}這樣的代碼對(duì),中間放置對(duì)應(yīng)頁面區(qū)域的html代碼,如在common.html中將頁面整體劃分了三個(gè)區(qū)域,header、container和footer。假設(shè)網(wǎng)站的每個(gè)網(wǎng)頁都擁有相同的header和footer部分,就可以在common.html中將這兩部分內(nèi)容設(shè)計(jì)好。如果需要修改,就直接修改這個(gè)文件即可,別的網(wǎng)頁就會(huì)即時(shí)響應(yīng)變化。container主體內(nèi)容部分肯定是每個(gè)頁面都是不一樣的。{% extends 'common.html' %} #導(dǎo)入模板文件{% block title %}產(chǎn)品頁面 {% endblock %} #修改模板中的網(wǎng)頁標(biāo)題內(nèi)容部分
保存好所有文件,重啟main.py服務(wù)器文件,然后打開瀏覽器,在地址欄輸入: http://127.0.0.1/product,其內(nèi)容顯示如下:<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>{% block title %}Title {% endblock %} </title> <style> .header,.footer{height:35px;width:100%;margin:0 auto;background:#333;color:#f0f0f0;} .header li{list-style:none;display:inline;width:300px;margin:0px 20px;} .container{height:100px;width:100%;border:1px solid #f30;} .footer{font-size:12px;text-align:center;height:20px;} </style></head><body> {% block header %} <div class="header"> #頭部區(qū)域的導(dǎo)航 <ul> <li>首頁</li> <li>最近新聞</li> <li>最新產(chǎn)品</li> <li>人力需求</li> <li>聯(lián)系我們</li> </ul> </div> {% endblock %} {% block container %} #中部?jī)?nèi)容塊區(qū)域 <div class="container">中部業(yè)務(wù)內(nèi)容</div> {% endblock %} {% block footer %} #底部區(qū)域 <div class="footer"> Made by PeterCao,2020.聯(lián)系方式:caoln2003@126.com </div> {% endblock %}</body></html>
然后再來瀏覽產(chǎn)品頁,效果就變成了:客戶&案例
營(yíng)銷資訊
關(guān)于我們
客戶&案例
營(yíng)銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2022 保留一切法律許可權(quán)利。