# 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')