日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python全栈开发:web框架们

發(fā)布時間:2025/3/15 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python全栈开发:web框架们 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python的WEB框架

Bottle

Bottle是一個快速、簡潔、輕量級的基于WSIG的微型Web框架,此框架只由一個 .py 文件,除了Python的標(biāo)準(zhǔn)庫外,其不依賴任何其他模塊。

1 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.org/bottle.py

Bottle框架大致可以分為以下部分:

  • 路由系統(tǒng),將不同請求交由指定函數(shù)處理
  • 模板系統(tǒng),將模板中的特殊語法渲染成字符串,值得一說的是Bottle的模板引擎可以任意指定:Bottle內(nèi)置模板、mako、jinja2、cheetah
  • 公共組件,用于提供處理請求相關(guān)的信息,如:表單數(shù)據(jù)、cookies、請求頭等
  • 服務(wù),Bottle默認支持多種基于WSGI的服務(wù),如:

?

server_names = {'cgi': CGIServer,'flup': FlupFCGIServer,'wsgiref': WSGIRefServer,'waitress': WaitressServer,'cherrypy': CherryPyServer,'paste': PasteServer,'fapws3': FapwsServer,'tornado': TornadoServer,'gae': AppEngineServer,'twisted': TwistedServer,'diesel': DieselServer,'meinheld': MeinheldServer,'gunicorn': GunicornServer,'eventlet': EventletServer,'gevent': GeventServer,'geventSocketIO':GeventSocketIOServer,'rocket': RocketServer,'bjoern' : BjoernServer,'auto': AutoServer, }

?

框架的基本使用

1 2 3 4 5 6 7 8 9 10 11 #!/usr/bin/env python # -*- coding:utf-8 -*- from?bottle?import?template, Bottle root?=?Bottle() @root.route('/hello/') def?index(): ????return?"Hello World" ????# return template('<b>Hello {{name}}</b>!', name="Alex") root.run(host='localhost', port=8080)

一、路由系統(tǒng)

路由系統(tǒng)是的url對應(yīng)指定函數(shù),當(dāng)用戶請求某個url時,就由指定函數(shù)處理當(dāng)前請求,對于Bottle的路由系統(tǒng)可以分為一下幾類:

  • 靜態(tài)路由
  • 動態(tài)路由
  • 請求方法路由
  • 二級路由

1、靜態(tài)路由

1 2 3 @root.route('/hello/') def?index(): ????return?template('<b>Hello {{name}}</b>!', name="Alex")

2、動態(tài)路由

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @root.route('/wiki/<pagename>') def?callback(pagename): ????... @root.route('/object/<id:int>') def?callback(id): ????... @root.route('/show/<name:re:[a-z]+>') def?callback(name): ????... @root.route('/static/<path:path>') def?callback(path): ????return?static_file(path, root='static')

3、請求方法路由

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @root.route('/hello/', method='POST') def?index(): ????... @root.get('/hello/') def?index(): ????... @root.post('/hello/') def?index(): ????... @root.put('/hello/') def?index(): ????... @root.delete('/hello/') def?index(): ????...

4、二級路由

#!/usr/bin/env python # -*- coding:utf-8 -*- from bottle import template, Bottleapp01 = Bottle()@app01.route('/hello/', method='GET') def index():return template('<b>App01</b>!')app01.py #!/usr/bin/env python # -*- coding:utf-8 -*- from bottle import template, Bottleapp02 = Bottle()@app02.route('/hello/', method='GET') def index():return template('<b>App02</b>!')app02.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/usr/bin/env python # -*- coding:utf-8 -*- from?bottle?import?template, Bottle from?bottle?import?static_file root?=?Bottle() @root.route('/hello/') def?index(): ????return?template('<b>Root {{name}}</b>!', name="Alex") from?framwork_bottle?import?app01 from?framwork_bottle?import?app02 root.mount('app01', app01.app01) root.mount('app02', app02.app02) root.run(host='localhost', port=8080)

二、模板系統(tǒng)

模板系統(tǒng)用于將Html和自定的值兩者進行渲染,從而得到字符串,然后將該字符串返回給客戶端。我們知道在Bottle中可以使用 內(nèi)置模板系統(tǒng)、mako、jinja2、cheetah等,以內(nèi)置模板系統(tǒng)為例:

<!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title> </head> <body><h1>{{name}}</h1> </body> </html>hello_template.tpl
1 2 3 4 5 6 7 8 9 10 11 12 #!/usr/bin/env python # -*- coding:utf-8 -*- from?bottle?import?template, Bottle root?=?Bottle() @root.route('/hello/') def?index(): ????# 默認情況下去目錄:['./', './views/']中尋找模板文件 hello_template.html ????# 配置在 bottle.TEMPLATE_PATH 中 ????return?template('hello_template.tpl', name='alex') root.run(host='localhost', port=8080)

1、語法

  • 單值
  • 單行Python代碼
  • Python代碼快
  • Python、Html混合

?

<h1>1、單值</h1> {{name}}<h1>2、單行Python代碼</h1> % s1 = "hello"<h1>3、Python代碼塊</h1> <%# A block of python codename = name.title().strip()if name == "Alex":name="seven" %><h1>4、Python、Html混合</h1>% if True:<span>{{name}}</span> % end <ul>% for item in name:<li>{{item}}</li>% end </ul>

?

2、函數(shù)?

include(sub_template, **variables)

1 2 3 4 5 # 導(dǎo)入其他模板文件 %?include('header.tpl', title='Page Title') Page Content %?include('footer.tpl')

rebase(name, **variables)

<html> <head><title>{{title or 'No title'}}</title> </head> <body>{{!base}} </body> </html>base.tpl
1 2 3 4 # 導(dǎo)入母版 %?rebase('base.tpl', title='Page Title') <p>Page Content ...</p>

defined(name)

1 # 檢查當(dāng)前變量是否已經(jīng)被定義,已定義True,未定義False

get(name, default=None)

1 # 獲取某個變量的值,不存在時可設(shè)置默認值

setdefault(name, default)

1 # 如果變量不存在時,為變量設(shè)置默認值

擴展:自定義函數(shù)

<!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title> </head> <body><h1>自定義函數(shù)</h1>{{ wupeiqi() }}</body> </html>hello_template.tpl ?hello_template.tpl ?main.py #!/usr/bin/env python # -*- coding:utf-8 -*- from bottle import template, Bottle,SimpleTemplate root = Bottle()def custom():return '123123'@root.route('/hello/') def index():# 默認情況下去目錄:['./', './views/']中尋找模板文件 hello_template.html# 配置在 bottle.TEMPLATE_PATH 中return template('hello_template.html', name='alex', wupeiqi=custom)root.run(host='localhost', port=8080)main.py

注:變量或函數(shù)前添加 【 ! 】,則會關(guān)閉轉(zhuǎn)義的功能

三、公共組件

由于Web框架就是用來【接收用戶請求】-> 【處理用戶請求】-> 【響應(yīng)相關(guān)內(nèi)容】,對于具體如何處理用戶請求,開發(fā)人員根據(jù)用戶請求來進行處理,而對于接收用戶請求和相應(yīng)相關(guān)的內(nèi)容均交給框架本身來處理,其處理完成之后將產(chǎn)出交給開發(fā)人員和用戶。

【接收用戶請求】

當(dāng)框架接收到用戶請求之后,將請求信息封裝在Bottle的request中,以供開發(fā)人員使用

【響應(yīng)相關(guān)內(nèi)容】

當(dāng)開發(fā)人員的代碼處理完用戶請求之后,會將其執(zhí)行內(nèi)容相應(yīng)給用戶,相應(yīng)的內(nèi)容會封裝在Bottle的response中,然后再由框架將內(nèi)容返回給用戶

所以,公共組件本質(zhì)其實就是為開發(fā)人員提供接口,使其能夠獲取用戶信息并配置響應(yīng)內(nèi)容。

1、request

Bottle中的request其實是一個LocalReqeust對象,其中封裝了用戶請求的相關(guān)信息:

request.headers請求頭信息request.queryget請求信息request.formspost請求信息request.files上傳文件信息request.paramsget和post請求信息request.GETget請求信息request.POSTpost和上傳信息request.cookiescookie信息request.environ環(huán)境相關(guān)相關(guān)

2、response

Bottle中的request其實是一個LocalResponse對象,其中框架即將返回給用戶的相關(guān)信息:

responseresponse.status_line狀態(tài)行response.status_code狀態(tài)碼response.headers響應(yīng)頭response.charset編碼response.set_cookie在瀏覽器上設(shè)置cookieresponse.delete_cookie在瀏覽器上刪除cookie

實例:

from bottle import route, request@route('/login') def login():return '''<form action="/login" method="post">Username: <input name="username" type="text" />Password: <input name="password" type="password" /><input value="Login" type="submit" /></form>'''@route('/login', method='POST') def do_login():username = request.forms.get('username')password = request.forms.get('password')if check_login(username, password):return "<p>Your login information was correct.</p>"else:return "<p>Login failed.</p>"基本Form請求 ?基本Form請求 ?上傳文件? <form action="/upload" method="post" enctype="multipart/form-data">Category: <input type="text" name="category" />Select a file: <input type="file" name="upload" /><input type="submit" value="Start upload" /> </form>@route('/upload', method='POST') def do_upload():category = request.forms.get('category')upload = request.files.get('upload')name, ext = os.path.splitext(upload.filename)if ext not in ('.png','.jpg','.jpeg'):return 'File extension not allowed.'save_path = get_save_path_for_category(category)upload.save(save_path) # appends upload.filename automaticallyreturn 'OK'上傳文件

四、服務(wù)

對于Bottle框架其本身未實現(xiàn)類似于Tornado自己基于socket實現(xiàn)Web服務(wù),所以必須依賴WSGI,默認Bottle已經(jīng)實現(xiàn)并且支持的WSGI有:

?WSGI server_names = {'cgi': CGIServer,'flup': FlupFCGIServer,'wsgiref': WSGIRefServer,'waitress': WaitressServer,'cherrypy': CherryPyServer,'paste': PasteServer,'fapws3': FapwsServer,'tornado': TornadoServer,'gae': AppEngineServer,'twisted': TwistedServer,'diesel': DieselServer,'meinheld': MeinheldServer,'gunicorn': GunicornServer,'eventlet': EventletServer,'gevent': GeventServer,'geventSocketIO':GeventSocketIOServer,'rocket': RocketServer,'bjoern' : BjoernServer,'auto': AutoServer, }WSGI

使用時,只需在主app執(zhí)行run方法時指定參數(shù)即可:

1 2 3 4 5 6 7 8 9 10 #!/usr/bin/env python # -*- coding:utf-8 -*- from?bottle?import?Bottle root?=?Bottle() @root.route('/hello/') def?index(): ????return?"Hello World" # 默認server ='wsgiref' root.run(host='localhost', port=8080, server='wsgiref')

默認server="wsgiref",即:使用Python內(nèi)置模塊wsgiref,如果想要使用其他時,則需要首先安裝相關(guān)類庫,然后才能使用。如:

?bottle.py源碼 # 如果使用Tornado的服務(wù),則需要首先安裝tornado才能使用class TornadoServer(ServerAdapter):""" The super hyped asynchronous server by facebook. Untested. """def run(self, handler): # pragma: no cover# 導(dǎo)入Tornado相關(guān)模塊import tornado.wsgi, tornado.httpserver, tornado.ioloopcontainer = tornado.wsgi.WSGIContainer(handler)server = tornado.httpserver.HTTPServer(container)server.listen(port=self.port,address=self.host)tornado.ioloop.IOLoop.instance().start()bottle.py源碼

PS:以上WSGI中提供了19種,如果想要使期支持其他服務(wù),則需要擴展Bottle源碼來自定義一個ServerAdapter

更多參見:http://www.bottlepy.org/docs/dev/index.html

Flask?

Flask是一個基于Python開發(fā)并且依賴jinja2模板和Werkzeug WSGI服務(wù)的一個微型框架,對于Werkzeug本質(zhì)是Socket服務(wù)端,其用于接收http請求并對請求進行預(yù)處理,然后觸發(fā)Flask框架,開發(fā)人員基于Flask框架提供的功能對請求進行相應(yīng)的處理,并返回給用戶,如果要返回給用戶復(fù)雜的內(nèi)容時,需要借助jinja2模板來實現(xiàn)對模板的處理,即:將模板和數(shù)據(jù)進行渲染,將渲染后的字符串返回給用戶瀏覽器。

“微”(micro) 并不表示你需要把整個 Web 應(yīng)用塞進單個 Python 文件(雖然確實可以 ),也不意味著 Flask 在功能上有所欠缺。微框架中的“微”意味著 Flask 旨在保持核心簡單而易于擴展。Flask 不會替你做出太多決策——比如使用何種數(shù)據(jù)庫。而那些 Flask 所選擇的——比如使用何種模板引擎——則很容易替換。除此之外的一切都由可由你掌握。如此,Flask 可以與您珠聯(lián)璧合。

默認情況下,Flask 不包含數(shù)據(jù)庫抽象層、表單驗證,或是其它任何已有多種庫可以勝任的功能。然而,Flask 支持用擴展來給應(yīng)用添加這些功能,如同是 Flask 本身實現(xiàn)的一樣。眾多的擴展提供了數(shù)據(jù)庫集成、表單驗證、上傳處理、各種各樣的開放認證技術(shù)等功能。Flask 也許是“微小”的,但它已準(zhǔn)備好在需求繁雜的生產(chǎn)環(huán)境中投入使用。

安裝

1 pip install Flask
?werkzeug #!/usr/bin/env python # -*- coding:utf-8 -*- from werkzeug.wrappers import Request, Response@Request.application def hello(request):return Response('Hello World!')if __name__ == '__main__':from werkzeug.serving import run_simplerun_simple('localhost', 4000, hello)werkzeug

一、第一次

1 2 3 4 5 6 7 8 9 from?flask?import?Flask app?=?Flask(__name__) @app.route("/") def?hello(): ????return?"Hello World!" if?__name__?==?"__main__": ????app.run()

二、路由系統(tǒng)

  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')
  • @app.route('/post/<path:path>')
  • @app.route('/login', methods=['GET', 'POST'])

常用路由系統(tǒng)有以上五種,所有的路由系統(tǒng)都是基于一下對應(yīng)關(guān)系來處理:

1 2 3 4 5 6 7 8 9 DEFAULT_CONVERTERS?=?{ ????'default':????????? UnicodeConverter, ????'string':?????????? UnicodeConverter, ????'any':????????????? AnyConverter, ????'path':???????????? PathConverter, ????'int':????????????? IntegerConverter, ????'float':??????????? FloatConverter, ????'uuid':???????????? UUIDConverter, }

注:對于Flask默認不支持直接寫正則表達式的路由,不過可以通過自定義來實現(xiàn),見:https://segmentfault.com/q/1010000000125259

三、模板

1、模板的使用

Flask使用的是Jinja2模板,所以其語法和Django無差別

2、自定義模板方法

Flask中自定義模板方法的方式和Bottle相似,創(chuàng)建一個函數(shù)并通過參數(shù)的形式傳入render_template,如:

<!DOCTYPE html> <html> <head lang="en"><meta charset="UTF-8"><title></title> </head> <body><h1>自定義函數(shù)</h1>{{ww()|safe}}</body> </html>index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env python # -*- coding:utf-8 -*- from?flask?import?Flask,render_template app?=?Flask(__name__) def?wupeiqi(): ????return?'<h1>Wupeiqi</h1>' @app.route('/login', methods=['GET',?'POST']) def?login(): ????return?render_template('login.html', ww=wupeiqi) app.run()

四、公共組件

1、請求

對于Http請求,Flask會講請求信息封裝在request中(werkzeug.wrappers.BaseRequest),提供的如下常用方法和字段以供使用:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 request.method request.args request.form request.values request.files request.cookies request.headers request.path request.full_path request.script_root request.url request.base_url request.url_root request.host_url request.host
?表單處理Demo ?上傳文件Demo ?Cookie操作 @app.route('/login', methods=['POST', 'GET']) def login():error = Noneif request.method == 'POST':if valid_login(request.form['username'],request.form['password']):return log_the_user_in(request.form['username'])else:error = 'Invalid username/password'# the code below is executed if the request method# was GET or the credentials were invalidreturn render_template('login.html', error=error)表單處理Demo from flask import request from werkzeug import secure_filename@app.route('/upload', methods=['GET', 'POST']) def upload_file():if request.method == 'POST':f = request.files['the_file']f.save('/var/www/uploads/' + secure_filename(f.filename))...上傳文件Demo from flask import request@app.route('/setcookie/') def index():username = request.cookies.get('username')# use cookies.get(key) instead of cookies[key] to not get a# KeyError if the cookie is missing.from flask import make_response@app.route('/getcookie') def index():resp = make_response(render_template(...))resp.set_cookie('username', 'the username')return respCookie操作

2、響應(yīng)

當(dāng)用戶請求被開發(fā)人員的邏輯處理完成之后,會將結(jié)果發(fā)送給用戶瀏覽器,那么就需要對請求做出相應(yīng)的響應(yīng)。

a.字符串

1 2 3 @app.route('/index/', methods=['GET',?'POST']) def?index(): ????return?"index"

b.模板引擎

1 2 3 4 5 6 7 8 from?flask?import?Flask,render_template,request app?=?Flask(__name__) @app.route('/index/', methods=['GET',?'POST']) def?index(): ????return?render_template("index.html") app.run()

c.重定向

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!/usr/bin/env python # -*- coding:utf-8 -*- from?flask?import?Flask, redirect, url_for app?=?Flask(__name__) @app.route('/index/', methods=['GET',?'POST']) def?index(): ????# return redirect('/login/') ????return?redirect(url_for('login')) @app.route('/login/', methods=['GET',?'POST']) def?login(): ????return?"LOGIN" app.run()

d.錯誤頁面

from flask import Flask, abort, render_template app = Flask(__name__)@app.route('/e1/', methods=['GET', 'POST']) def index():abort(404, 'Nothing') app.run()指定URL,簡單錯誤
1 2 3 4 5 6 7 8 9 10 11 12 from?flask?import?Flask, abort, render_template app?=?Flask(__name__) @app.route('/index/', methods=['GET',?'POST']) def?index(): ????return?"OK" @app.errorhandler(404) def?page_not_found(error): ????return?render_template('page_not_found.html'),?404 app.run()

e.設(shè)置相應(yīng)信息

使用make_response可以對相應(yīng)的內(nèi)容進行操作

1 2 3 4 5 6 7 8 9 10 11 12 13 from?flask?import?Flask, abort, render_template,make_response app?=?Flask(__name__) @app.route('/index/', methods=['GET',?'POST']) def?index(): ????response?=?make_response(render_template('index.html')) ????# response是flask.wrappers.Response類型 ????# response.delete_cookie ????# response.set_cookie ????# response.headers['X-Something'] = 'A value' ????return?response app.run()

3、Session

除請求對象之外,還有一個 session 對象。它允許你在不同請求間存儲特定用戶的信息。它是在 Cookies 的基礎(chǔ)上實現(xiàn)的,并且對 Cookies 進行密鑰簽名要使用會話,你需要設(shè)置一個密鑰。

  • 設(shè)置:session['username'] = 'xxx'

  • 刪除:session.pop('username', None)
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 from?flask?import?Flask, session, redirect, url_for, escape, request app?=?Flask(__name__) @app.route('/') def?index(): ????if?'username'?in?session: ????????return?'Logged in as %s'?%?escape(session['username']) ????return?'You are not logged in' @app.route('/login', methods=['GET',?'POST']) def?login(): ????if?request.method?==?'POST': ????????session['username']?=?request.form['username'] ????????return?redirect(url_for('index')) ????return?''' ????????<form action="" method="post"> ????????????<p><input type=text name=username> ????????????<p><input type=submit value=Login> ????????</form> ????''' @app.route('/logout') def?logout(): ????# remove the username from the session if it's there ????session.pop('username',?None) ????return?redirect(url_for('index')) # set the secret key.? keep this really secret: app.secret_key?=?'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

4.message

message是一個基于Session實現(xiàn)的用于保存數(shù)據(jù)的集合,其特點是:使用一次就刪除

?index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from?flask?import?Flask, flash, redirect, render_template, request app?=?Flask(__name__) app.secret_key?=?'some_secret' @app.route('/') def?index1(): ????return?render_template('index.html') @app.route('/set') def?index2(): ????v?=?request.args.get('p') ????flash(v) ????return?'ok' if?__name__?==?"__main__": ????app.run()

5.中間件

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 from?flask?import?Flask, flash, redirect, render_template, request app?=?Flask(__name__) app.secret_key?=?'some_secret' @app.route('/') def?index1(): ????return?render_template('index.html') @app.route('/set') def?index2(): ????v?=?request.args.get('p') ????flash(v) ????return?'ok' class?MiddleWare: ????def?__init__(self,wsgi_app): ????????self.wsgi_app?=?wsgi_app ????def?__call__(self,?*args,?**kwargs): ????????return?self.wsgi_app(*args,?**kwargs) if?__name__?==?"__main__": ????app.wsgi_app?=?MiddleWare(app.wsgi_app) ????app.run(port=9999)

Flask還有眾多其他功能,更多參見:
? ? http://docs.jinkan.org/docs/flask/
? ??http://flask.pocoo.org/

轉(zhuǎn)載于:https://www.cnblogs.com/nixingguo/p/6613584.html

總結(jié)

以上是生活随笔為你收集整理的Python全栈开发:web框架们的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。