Python的Bottle框架的一些使用技巧介绍


Posted in Python onApril 08, 2015

之前对bottle做过不少的介绍,也写过一些文章来说明bottle的缺点,最近发现其实之前有些地方说的不太公平,所以趁此机会也来更正一下。

    bottle是支持类似flask url_for的语法的,具体使用方法在下文介绍
    bottle的request.query之类的参数默认是str类型,也是有原因的,比如我在给google做代理的时候,编码就不一定是utf8的,如果强制转化utf8就会报错
    之前的bug也得到了修正,比如mount(‘/x',app)之后,/x/和/x都可以访问到

OK,现在正式进入主题,我们来介绍一些bottle的一些高级使用

一. 智能创建url

这部分在bottle的文档上是没有介绍的(其实bottle明明实现了很多贴心的功能,不知道为啥都不写在文档上)。
在Bottle类里,有一个成员函数:

def get_url(self, routename, **kargs):
  """ Return a string that matches a named route """
  scriptname = request.environ.get('SCRIPT_NAME', '').strip('/') + '/'
  location = self.router.build(routename, **kargs).lstrip('/')
  return urljoin(urljoin('/', scriptname), location)
 
def get_url(self, routename, **kargs):
  """ Return a string that matches a named route """
  scriptname = request.environ.get('SCRIPT_NAME', '').strip('/') + '/'
  location = self.router.build(routename, **kargs).lstrip('/')
  return urljoin(urljoin('/', scriptname), location)

那么这个routename是哪里来的呢?看 route 装饰器的参数:

def route(self, path=None, method='GET', callback=None, name=None,
     apply=None, skip=None, **config):
 
def route(self, path=None, method='GET', callback=None, name=None,
     apply=None, skip=None, **config):

其中的name参数就是routename(这里不得不说一下,这种方式比flask要好些,要用才指定name,而不需要为了实现url_for,把整个框架都实现的很复杂)

所以看到这里大家也就明白了,bottle的url生成器是绑定在Bottle实例上的,所以跨实例访问默认是做不到的。
而可能由于bottle所推崇的micro化,所以其源码中特意对默认Bottle示例包装出了一个函数:

for name in '''route get post put delete error mount
        hook install uninstall'''.split():
  globals()[name] = make_default_app_wrapper(name)
url = make_default_app_wrapper('get_url')
del name
 
for name in '''route get post put delete error mount
        hook install uninstall'''.split():
  globals()[name] = make_default_app_wrapper(name)
url = make_default_app_wrapper('get_url')
del name

这样做的好处是,如果工程只用到默认的Bottle实例的话,在模板中就可以直接使用url,而不必再多传个Bottle实例进去。

更正一下,bottle的get_url是不能跨app调用的,比如被mount的app调用主app的get_url会错掉,因为此时的SCRIPT_NAME是当前页的path,所以拼装起来会乱掉,所以就不要尝试了。

但是怎么才能让模板能够访问到local变量呢?我们接下来介绍

二. 给模板指定默认的变量

因为笔者用的最多的是jinja2,所以模板相关的介绍都是以jinja2为例子.
由于bottle的很多实例都是使用的代理模式,如request,response,local,所以我们可以放心的将这些变量传入到模板默认变量里去。
代码也很简单:

from bottle import BaseTemplate

BaseTemplate.defaults.update(dict(
  request=request,
  local=local,
  )
)
 
from bottle import BaseTemplate
 
BaseTemplate.defaults.update(dict(
  request=request,
  local=local,
  )
)

有兴趣的话,大家也可以去直接看一下源码,很好懂

三. 给模板增加filters

还是以jinja2为例,直接给出代码如下:

from bottle import BaseTemplate

if 'filters' not in BaseTemplate.settings:
  BaseTemplate.settings['filters'] = {}

filters = BaseTemplate.settings['filters']

def urlencode_filter(params):
  '''
  urlencode
  '''
  from urllib import urlencode

  return urlencode(params)

filters.update(dict(
  urlencode=urlencode_filter,
  )
)
 
from bottle import BaseTemplate
 
if 'filters' not in BaseTemplate.settings:
  BaseTemplate.settings['filters'] = {}
 
filters = BaseTemplate.settings['filters']
 
def urlencode_filter(params):
  '''
  urlencode
  '''
  from urllib import urlencode
 
  return urlencode(params)
 
filters.update(dict(
  urlencode=urlencode_filter,
  )
)

OK,一共就是这些,这里基于的bottle版本是 0.10.9,如果有不相符的地方,请查看bottle版本。

Python 相关文章推荐
详解Python编程中对Monkey Patch猴子补丁开发方式的运用
May 27 Python
详解tensorflow训练自己的数据集实现CNN图像分类
Feb 07 Python
python使用sqlite3时游标使用方法
Mar 13 Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 Python
python自定义时钟类、定时任务类
Feb 22 Python
详解Python中的正斜杠与反斜杠
Aug 09 Python
django 多对多表的创建和插入代码实现
Sep 09 Python
Python logging模块进行封装实现原理解析
Aug 07 Python
python中使用np.delete()的实例方法
Feb 01 Python
Python对excel的基本操作方法
Feb 18 Python
用python批量解压带密码的压缩包
May 31 Python
Elasticsearch 索引操作和增删改查
Apr 19 Python
在Python的框架中为MySQL实现restful接口的教程
Apr 08 #Python
简单介绍Python的轻便web框架Bottle
Apr 08 #Python
常见的在Python中实现单例模式的三种方法
Apr 08 #Python
分析Python的Django框架的运行方式及处理流程
Apr 08 #Python
给Python的Django框架下搭建的BLOG添加RSS功能的教程
Apr 08 #Python
在Python中使用NLTK库实现对词干的提取的教程
Apr 08 #Python
使用Python操作Elasticsearch数据索引的教程
Apr 08 #Python
You might like
我的php学习笔记(毕业设计)
2012/02/21 PHP
Ubuntu VPS中wordpress网站打开时提示”建立数据库连接错误”的解决办法
2016/11/03 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
Laravel中任务调度console使用方法小结
2017/05/07 PHP
一次因composer错误使用引发的问题与解决
2019/03/06 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
jQuery 阴影插件代码分享
2012/01/09 Javascript
关于jquery input textare 事件绑定及用法学习
2013/04/03 Javascript
jQuery学习笔记(2)--用jquery实现各种模态提示框代码及项目构架
2013/04/08 Javascript
JS不能跨域借助jquery获取IP地址的方法
2014/08/20 Javascript
javascript的push使用指南
2014/12/05 Javascript
jQuery+easyui中的combobox实现下拉框特效
2015/02/27 Javascript
Backbone.js的一些使用技巧
2015/07/01 Javascript
jQuery实现固定在网页顶部的菜单效果代码
2015/09/02 Javascript
跟我学习javascript的prototype,getPrototypeOf和__proto__
2015/11/17 Javascript
实例详解jQuery结合GridView控件的使用方法
2016/01/04 Javascript
Bootstrap3使用typeahead插件实现自动补全功能
2016/07/07 Javascript
常用原生js自定义函数总结
2016/11/20 Javascript
js中document.referrer实现移动端返回上一页
2017/02/22 Javascript
JS+HTML+CSS实现轮播效果
2017/11/28 Javascript
webpack打包node.js后端项目的方法
2018/03/10 Javascript
node结合swig渲染摸板的方法
2018/04/11 Javascript
Webpack之tree-starking 解析
2018/09/11 Javascript
jquery实现加载更多"转圈圈"效果(示例代码)
2020/11/09 jQuery
python中的sort方法使用详解
2014/07/25 Python
Python实现将多个空格换为一个空格.md的方法
2018/12/20 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
opencv python统计及绘制直方图的方法
2019/01/21 Python
python使用for循环计算0-100的整数的和方法
2019/02/01 Python
python使用HTMLTestRunner导出饼图分析报告的方法
2019/12/30 Python
Tensorflow 1.0之后模型文件、权重数值的读取方式
2020/02/12 Python
通过实例了解python__slots__使用方法
2020/09/14 Python
学习标兵获奖感言
2014/02/20 职场文书
2014年小学图书室工作总结
2014/12/09 职场文书
美丽心灵观后感
2015/06/01 职场文书
SpringBoot使用AOP实现统计全局接口访问次数详解
2022/06/16 Java/Android