瓶子:使用jinja2_view装饰器

时间:2017-05-24 17:21:29

标签: python jinja2 bottle python-decorators

如果我直接从瓶子导入post,get和jinja2_view,我可以使用jinja2_view作为装饰者:

from bottle import get, post, request, run, jinja2_view

@jinja2_view('index.html')
@get('/')
def index():
    return

run(host='localhost', port=8080, debug=True, reloader=True)

但是如果我导入并使用Bottle()构造函数,我就不能再使用jinja装饰器了:

from bottle import Bottle, get, post, request, run, jinja2_view

app = Bottle()

@app.jinja2_view('index.html')
@app.get('/')
def index():
    return

run(app, host='localhost', port=8080, debug=True, reloader=True)

我明白了:

Traceback (most recent call last):
  File "webserver.py", line 10, in <module>
    @app.jinja2_view('index.html')
AttributeError: 'Bottle' object has no attribute 'jinja2_view'

如何将jinja2_view与Bottle()构造函数一起使用? (构造函数是必要的,因为我使用的是需要app.install(plugin)的mysql库。

编辑1

如果我将@app.get()@jinja2_view一起使用,则回调函数无权访问该插件

from bottle import get, post, request, run, jinja2_view, Bottle

import bottle_mysql

app = Bottle()
plugin = bottle_mysql.Plugin(dbuser='bottle',dbpass='password', dbname='mydb')
app.install(plugin)

@app.get('/now')
@jinja2_view('now.html')
def get_now(db):
    db.execute('SELECT now() as now')
    row = db.fetchone()
    now = str(row['now'])
    return { 'now': now }

run(app, host='localhost', port=8080, debug=True, reloader=True)

例外:

TypeError('get_now() takes exactly 1 argument (0 given)',)

如果我注释掉@jinja2_view('now.html'),则路由起作用并返回正确的json响应。

2 个答案:

答案 0 :(得分:1)

你不能这样做,因为正如错误所说,Bottle类没有属性jinja2_view。但是如果你同时使用它们都是没有问题的,每个都是为了它的目的:Bottle()来实例化你的app,jinja2_view来渲染模板。

答案 1 :(得分:1)

jinja2_view是由bottle模块提供的函数,它不是Bottle类的类方法。 因此,当您调用@app.jinja2_view时,python会搜索app(这是bottle.Bottle的一个实例),这个属性名为jinja2_view,它显然无法找到。

因此,您有两个非常简单的选项来纠正这个问题:

  1. 您可以返回使用@jinja2_view('index.html')
  2. 只需导入瓶子并使用所有瓶子方法的完全限定的命名空间,例如: @bottle.jinja2_view('index.html')app = bottle.Bottle()
  3. 我个人非常偏爱后者,因为它避免了对全局命名空间的意外污染,这可能很重要,因为围绕网络服务器构建的这些小项目往往会随着时间的推移而增长和膨胀。当然,您的里程可能会有所不同。

    修改

    我根据你的原创创建了一个更简单的例子,希望这有助于确定问题所在。试试这个:

    from bottle import get, run, jinja2_view, Bottle
    import datetime
    
    app = Bottle()
    @app.get('/now')
    @jinja2_view('now.html')
    def get_now():
        now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        return { 'now': now }
    
    run(app, host='localhost', port=8080, debug=True)
    

    在浏览器中查看此内容会在<h1>元素中正确呈现日期时间字符串。如果它也适合你,问题可能在于插件。