diff --git a/flask.py b/flask.py index 1dfe8a8f..8ed62509 100644 --- a/flask.py +++ b/flask.py @@ -481,9 +481,9 @@ class Flask(object): """ session.save_cookie(response, self.session_cookie_name) - def add_url_rule(self, rule, endpoint, **options): + def add_url_rule(self, rule, endpoint, view_func=None, **options): """Connects a URL rule. Works exactly like the :meth:`route` - decorator but does not register the view function for the endpoint. + decorator. If a view_func is provided it will be registered with the endpoint. Basically this example:: @@ -495,19 +495,25 @@ class Flask(object): def index(): pass - app.add_url_rule('index', '/') + app.add_url_rule('/', 'index', index) + + If the view_func is not provided you will need to connect the endpoint to a + view function like so: app.view_functions['index'] = index :param rule: the URL rule as string :param endpoint: the endpoint for the registered URL rule. Flask itself assumes the name of the view function as endpoint + :param view_func: the function to call when servicing a request to the provided endpoint :param options: the options to be forwarded to the underlying :class:`~werkzeug.routing.Rule` object """ options['endpoint'] = endpoint options.setdefault('methods', ('GET',)) self.url_map.add(Rule(rule, **options)) + if view_func is not None: + self.view_functions[endpoint] = view_func def route(self, rule, **options): """A decorator that is used to register a view function for a diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 2d1f85f4..15166e9a 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -57,6 +57,30 @@ class BasicFunctionalityTestCase(unittest.TestCase): assert rv.status_code == 405 assert sorted(rv.allow) == ['GET', 'HEAD', 'POST'] + def test_url_mapping(self): + app = flask.Flask(__name__) + def index(): + return flask.request.method + def more(): + return flask.request.method + + app.add_url_rule('/', 'index', index) + app.add_url_rule('/more', 'more', more, methods=['GET', 'POST']) + + c = app.test_client() + assert c.get('/').data == 'GET' + rv = c.post('/') + assert rv.status_code == 405 + assert sorted(rv.allow) == ['GET', 'HEAD'] + rv = c.head('/') + assert rv.status_code == 200 + assert not rv.data # head truncates + assert c.post('/more').data == 'POST' + assert c.get('/more').data == 'GET' + rv = c.delete('/more') + assert rv.status_code == 405 + assert sorted(rv.allow) == ['GET', 'HEAD', 'POST'] + def test_session(self): app = flask.Flask(__name__) app.secret_key = 'testkey'