Flask Blueprint url_for BuildError when using add_url_rule

Question:

I am stuck in blueprint when I am trying to use flask blueprint in the way of add_url_rule

Here’s my flask project structure:

myapp
... __init__.py
... app.py
... model
... static
... views
...... main.py
... templates
...... base.html
...... results.html

In main.py,Here is my code:

from flask import Flask, url_for, Blueprint
main_bp = Blueprint('main', __name__)

def home():
    return redirect(url_for('main.results'))

def results():
    # some code
    return render_template('result.html')

and In my app.py, Here’s the code:

from myapp.views.main import main_bp

app.register_blueprint(main_bp)

app.add_url_rule('/', view_func=main.home)

app.add_url_rule('/results', view_func=main.results, methods=['POST', 'GET'])

when I am visiting the index page, I always got the following error message:

Traceback (most recent call last):
File "/Users/deamon/venv/src/staticngclient/staticng_client/middlewares/wsgi.py", line 25, in __call__
return app(environ, start_response)
File "/Users/deamon/venv/src/daeprofiling/dae_profiling/middleware.py", line 24, in __call__
  return self.app(environ, start_response)
File "/Users/deamon/venv/src/doubancommonlib/douban/common/middleware/content_filter.py", line 18, in __call__
  app_iter = self.application(environ, response.start_response)
File "/Users/deamon/dae/app/web.py", line 77, in __call__
  return handler(environ, start_response)
File "/Users/deamon/Projects/dae/dae/handlers/__init__.py", line 65, in __call__
  return self.app(environ, start_response)
File "/Users/deamon/Projects/dae/dae/handlers/web.py", line 46, in __call__
  return self._app(*a, **kw)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
  return self.wsgi_app(environ, start_response)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
  response = self.make_response(self.handle_exception(e))
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
  reraise(exc_type, exc_value, tb)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
  response = self.full_dispatch_request()
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
  rv = self.handle_user_exception(e)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
  reraise(exc_type, exc_value, tb)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
  rv = self.dispatch_request()
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
  return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/deamon/kiwi/views/main.py", line 19, in home
  return redirect(url_for('main.results'))
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/helpers.py", line 312, in url_for
  return appctx.app.handle_url_build_error(error, endpoint, values)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/app.py", line 1641, in handle_url_build_error
  reraise(exc_type, exc_value, tb)
File "/Users/deamon/venv/lib/python2.7/site-packages/flask/helpers.py", line 305, in url_for
  force_external=external)
File "/Users/deamon/venv/lib/python2.7/site-packages/werkzeug/routing.py", line 1678, in build
  raise BuildError(endpoint, values, method)
BuildError: ('main.results', {}, None)

also, in mye templates, such as base.html or results.html, when I am using

        <a class="navbar-brand" href="{{ url_for('main.home') }}">kiwi</a>

the same error occurs.

Can someone help?

Asked By: shitoujizu

||

Answers:

Ok, so the first problem I see that is even though you’re trying to use blueprint you’re not actually doing anything with it.

Yeah, in the line main_bp = Blueprint('main', __name__) you create it, but after that you don’t actually register any url endpoints for it and instead try to do it via imports in the main app.

Because you don’t actually register the endpoints in the blueprint but try to create redirect for it by calling main.results with prefix to the blueprint ‘main’ your url_for function fails.

This is how your code would look with proper use of blueprints

blueprint

from flask import Flask, url_for, Blueprint
main_bp = Blueprint('main', __name__)

@main_bp.route('/') 
def home():
    return redirect(url_for('main.results'))

@main_bp.route('/results') 
def results():
    # some code
    return render_template('result.html')

and app.py

from myapp.views.main import main_bp

app.register_blueprint(main_bp)

Or if you want to use add_url_rule (which works exactly like the decorator) just use main_bp.add_url_rule(...) in the blueprint file.

Working example with add_url_rule

Blueprint file

from flask import Flask, url_for, Blueprint, redirect, render_template
main_bp = Blueprint('main', __name__)

def home():
    return redirect(url_for('main.results'))

def results():
    # some code
    return 'some results'

main_bp.add_url_rule('/', view_func=home)
main_bp.add_url_rule('/results', view_func=results)

app file

from flask import Flask
import bp

app = Flask(__name__)


app.register_blueprint(bp.main_bp)



if __name__ == '__main__':
    app.run()
Answered By: MadRabbit
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.