-
-
Save gingerlime/9023629 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
# coding=utf8 | |
from flask import Flask, Blueprint, redirect, url_for | |
from flask.ext.bootstrap import Bootstrap | |
bp = Blueprint('blueprint', __name__) | |
app = Flask(__name__) | |
Bootstrap(app) | |
app.register_blueprint(bp, prefix='/prefix') | |
# when using `@app.route` this works, but url is `/` | |
# with @bp.route neither `/` nor `/prefix` work | |
@bp.route('/', methods=('GET', 'POST',)) | |
def index(): | |
return 'index' | |
@bp.route('/go_home') | |
def go_home(): | |
return redirect(url_for('index')) | |
if '__main__' == __name__: | |
app.run(debug=True) |
Example::
#!/usr/bin/env python
# coding=utf8
from flask import Flask, Blueprint, redirect, url_for
from flask.ext.bootstrap import Bootstrap
bp = Blueprint('blueprint', __name__)
# when using `@app.route` this works, but url is `/`
# with @bp.route neither `/` nor `/prefix` work
@bp.route('/', methods=('GET', 'POST',))
def index():
return 'index'
@bp.route('/go_home')
def go_home():
return redirect(url_for('index'))
app = Flask(__name__)
Bootstrap(app)
app.register_blueprint(bp, prefix='/prefix')
if '__main__' == __name__:
app.run(debug=True)
Also note that this problem does not even occur if you move each blueprint to a separate file, as you should (though it's good to have tried and run into this problem and learned something from it =)).
Another thing to adopt is the create app pattern: http://flask.pocoo.org/docs/patterns/appfactories/
Finally, you could end up with a structure like this:
myapp/__init__.py
:
from flask import Flask
from flask_bootstrap import Bootstrap # note that flask.ext. is deprecated, use flask_ instead for newer extensions
from flask_appconfig import AppConfig # optional and disclaimer: I wrote flask-appconfig. see https://github.com/mbr/flask-appconfig
from .someblueprint import someblueprint
def create_app(configfile=None):
app = Flask(__name__)
AppConfig(app)
Bootstrap(app)
app.register_blueprint(someblueprint, prefix='/prefix')
return app
myapp/someblueprint.py
from flask import Blueprint
someblueprint = Blueprint('someblueprint', __name__)
@someblueprint.route('/', methods=('GET', 'POST',))
def index():
return 'index'
@someblueprint.route('/go_home')
def go_home():
# note that i'm using '.index', not 'index' - the latter would redirect to the app, not the blueprint
return redirect(url_for('.index'))
Since it's now a package __init__.py
file, you cannot run the application using ifmain anymore. Therefore you need to write something like this apprunner.py
:
from myapp import create_app
create_app().run(debug=True)
Of course, if you use appconfig, you can eschew this step when developing (using flaskdev
, see the appconfig docs for details). Finally, all this requires a working virtualenv and setup.py
, but that'll you'll have to google for yourself.
Good luck.
Wow. Thanks a bunch @mbr. So much useful and clear info. I definitely learned something (actually, learned way-more than I expected). And interestingly, I was thinking about tackling how to manage configs, so flask-appconfig looks very useful as well.
To be honest, as a side-note, this whole thing started as an experiment using a micro-framework after working for some time with Django/Rails. So my thinking was doing something quick-n-dirty, and keeping almost everything in one file. It is essentially a one-form app to charge credit cards via stripe. I realise that things evolve rather quickly and soon enough you have to start splitting and tidying-up, managing configs etc. So I'm beginning to wonder if micro-frameworks really save so much. But I certainly appreciate the experience, and having kind people to help me like you did is very encouraging, regardless of the framework or technology. I'm very thankful for your help Marc!
just noticed that in some places in the documentation, e.g. https://pypi.python.org/pypi/Flask-Bootstrap and http://pythonhosted.org/Flask-Bootstrap/bootstrap2.html?highlight=ext#usage - it still shows the deprecated method of importing Bootstrap from flask.ext.bootstrap import Bootstrap
You're doing things in the wrong order. =)
When you register the blueprint, it adds its own routes to the app - at that point no routes are defined. The fix is simply moving the app below the creation of the blueprint. See the example below: