Reputation: 625
If I import post, get, and jinja2_view directly from bottle, I'm able to use a jinja2_view as a decorator:
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)
But if I import and use the Bottle()
constructor, I can no longer use the jinja decorator:
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)
I get:
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'
How can I use jinja2_view with the Bottle()
constructor? (the constructor is necessary because I'm using a mysql lib that requires app.install(plugin)
.
If I use @app.get()
together with @jinja2_view
the callback function doesn't have access to the plugin
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)
Exception:
TypeError('get_now() takes exactly 1 argument (0 given)',)
If I comment out @jinja2_view('now.html')
the route works and returns the correct json response.
Upvotes: 1
Views: 1270
Reputation: 1291
jinja2_view
is a function provided by the bottle module, it is not a class method of the Bottle
class.
Therefore, when you call @app.jinja2_view
, python searchs app
(which is an instance of bottle.Bottle
) for an attribute called jinja2_view, which it obviously fails to find.
So, you have two really easy options to correct this:
@jinja2_view('index.html')
.@bottle.jinja2_view('index.html')
and app = bottle.Bottle()
.I personally have a strong preference for the latter, as it avoids accidental pollution of the global namespace, which can be important as these small projects build around webservers tend to grow and bloat over time. Of course, your mileage may vary.
I've created an even simpler example based off your original, hopefully this will help determine where the problem lies. Try running this:
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)
Viewing this in the browser renders the datetime string correctly within an <h1>
element. If it works for you as well, the problem may lie with the plugin.
Upvotes: 2