# Bottle 1.簡單運行bottle框架 from bottle import template, Bottle root = Bottle() @root.route('/hello/') def index(): return 'hello world' root.run(host='localhost', port=8080) 2.路由系統 # web框架常見3類路由系統:裝飾器,urlconf對應關系,反射; # 1.靜態路由 @root.route('/hello/') def index(): return template('<b>hello {{name}}</b>',name='Alex') # 2.動態路由 @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.請求方法路由 @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.二級路由|沒看明白!!!!############################################ # app01|二級路由 from bottle import template, Bottle app01 = Bottle() @app01.route('/hello/', method='GET') def index(): return template('<b>App01</b>!') # app02|二級路由 from bottle import template, Bottle app02 = Bottle() @app02.route('/hello/', method='GET') def index(): return template('<b>App02</b>!') # 根路由 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 # 參數1表示url前綴; root.mount('app01', app01.app01) root.mount('app02', app02.app02) root.run(host='localhost', port=8080) 3.訪問靜態文件 @root.route('/statics/<path:path>') def callback(path): return static_file(path, root='static') # static/css/body.css body{ background-color: red; } # # 訪問:http://localhost:8080/statics/css/body.css 將直接訪問真實路徑static/css/body.css 4.前端渲染文字 from bottle import template, Bottle root = Bottle() @root.route('/hello/') def index(): # 將name值通過模板標簽{{name}}傳遞到前端展示; return template('<b>hello {{name}}</b>!', name='Mic') root.run(host='localhost', port=8080) 5.渲染頁面 # 模板路徑:templates/index.html from bottle import template, Bottle root = Bottle() @root.route('/hello/') def index(): return template('index.html') root.run(host='localhost', port=8080) # 默認在['./','./views/']目錄下尋找html文件,所以在templates目錄下無法找到該頁面; # 所以需要添加模板路徑配置; # bottle.TEMPLATE_PATH中; # 可以創建一個views文件夾來存放模板文件; # 或者,在TEMPLATE_PATH中列表中append自定義的路徑; import bottle bottle.TEMPLATE_PATH.append('./templates/') # 這樣就找到模板文件; 6.簡單login # my_web.py from bottle import template, Bottle root = Bottle() @root.route('/login/') def login(): return template('login.html') root.run(host='localhost', port=8080) # templates/login.html <body> <h1>用戶登錄</h1> <form action="/login/" method="post"> <input type="text" name="user" placeholder="username"> <input type="text" name="pwd" placeholder="password"> <input type="submit" value="submit"> </form> </body> # 問題:Method not allowed POST提交被拒絕; # 措施:在路由裝飾器中添加請求方式參數; @root.route('/login/', method='POST') # 此時GET方法就無法訪問了; # method參數可以以列表的方式傳入請求方式,比如['POST','GET','DELETE'...] # 另一種寫法: 將不同請求方式參數的裝飾器分別按在名字相同的視圖函數之上,其實已經不是同一個函數了; @root.route('/login/',method='POST') def login(): return template('login.html') @root.route('/login/',method='GET') def login(): return template('login.html') 7.上傳文件 # file_upload.html <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> # bottle_web.py @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 automatically return 'OK' 8.request判斷請求方式 # my_web.py from bottle import request @root.route('/login/', method=['GET','POST']) def login(): print(request.method) if request.method == "GET": return template('login.html') else: # 從input框中取值 ret = request.forms # >> <bottle.FormsDict object at 0x0000003D85A261D0> ret = request.query # >> <bottle.FormsDict object at 0x00000081B1366240> ret = request.body # >> <_io.BytesIO object at 0x000000A1E7FE3258> user = request.forms.get('user') pwd = request.forms.get('pwd') # >> FormsDict對象中獲取數據 print(ret,user,pwd) return template('login.html') # LocalRequest對象封裝的用戶請求信息如下: ######################### request.headers 請求頭信息 request.query get請求信息 request.forms post請求信息 request.files 上傳文件信息 request.params get和post請求信息 request.GET get請求信息 request.POST post和上傳信息 request.cookies cookie信息 request.environ 環境相關相關 ######################### 9.redirect頁面跳轉 # my_web.py from bottle import request,redirect @root.route('/login/', method=['GET','POST']) def login(): print(request.method) if request.method == "GET": return template('login.html') else: user = request.forms.get('user') pwd = request.forms.get('pwd') # >> FormsDict對象中獲取數據 print(ret,user,pwd) return redirect('/index/') 10.模板語言 ORM -- SqlAchemy 模板引擎 -- JinJia2 | 與django基本上差不多; # 在bottle中,有獨立的模板語言; # 1.單值; {{ name }} # 2.聲明; % sex = 'female' {{ sex }} # 3.代碼塊; 延用python代碼; <% _sex = sex.upper() if _sex == "FEMALE": sex = _sex %> {{ sex }} # 4.python代碼與html混合; % if True: <span>{{name}}</span> % end % for i in user_list: <li>{{ i }}</li> <li>{{ i['name'] }}</li> % end # 5.include -->> 包含; # % inculde('html',**params) % include('base.html',title='base_title') # 第2個參數的使用: # base.html <b>iiii</b> {{title}} # index.html % include('base.html',title='base_title') >> iiii base_title # 給傳進來的參數賦值,並在當前頁面中顯示; # 6.rebase -->> 繼承; # % rebase('',**params) # base.html <b>父模板</b> {{ title or 'pic' }} {{ !base }} # index.html % rebase('base.html',title='mic') >> 顯示:父模板 mic # % rebase('base.html',title=''),如果base中寫了title,子模板就必須寫title參數,即便為空; # 顯示:父模板 pic # 7.defined(name) # 檢查當前變量有沒被定義,返回True,False; # 8.get(name,default=None) # 獲取變量的值,如果不存在,返回自己設置的默認值; # 9.setdefault(name,default) # 如果變量不存在,為變量設置默認值; # 10.自定義函數;類似於django的simple_tag的作用; # bottle_web.py def simple_tag(): return 'hello' @root.route('/index/', method='GET') def index(): return template('index.html',func_name=simple_tag) # index.html {{ func_name() }} # 將自定義的函數傳進去,就可以在模板中執行; # 11.html轉義|執行函數時加一個'!' # bottle_web.py def simple_tag(): return '<h1>hello</h1>' @root.route('/index/', method='GET') def index(): return template('index.html',func_name=simple_tag) # index.html {{ !func_name() }} # 如果要使用其它模板引擎,比如Jinjia2 # bottle_web.py from bottle import Bottle from bottle import jinja2_template import bottle bottle.TEMPLATE_PATH.append('./templates/') root = Bottle() @root.route('/index/', method='GET') def index(): return jinja2_template('index.html') root.run(host='localhost', port=8080) # 使用Jinja2,那么模板語言跟django就是一樣的; 11.選擇使用Server # 更換不同的Server,socket實現不同; # 選擇參數: 使用前需安裝相應的包; 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, } # root.run(host='localhost', port=8080, server='CGIServer')