diff --git a/CHANGES b/CHANGES index aa7fcf34..3562bf90 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ Relase date to be decided, codename to be chosen. - The :func:`flask.url_for` function now can generate anchors to the generated links. +- The :func:`flask.url_for` function now can also explicitly generate + URL rules specific to a given HTTP method. - Logger now only returns the debug log setting if it was not set explicitly. diff --git a/flask/helpers.py b/flask/helpers.py index 62b6a3a4..7295dc3c 100644 --- a/flask/helpers.py +++ b/flask/helpers.py @@ -187,12 +187,13 @@ def url_for(endpoint, **values): For more information, head over to the :ref:`Quickstart `. .. versionadded:: 0.9 - The `_anchor` parameter was added. + The `_anchor` and `_method` parameters were added. :param endpoint: the endpoint of the URL (name of the function) :param values: the variable arguments of the URL rule :param _external: if set to `True`, an absolute URL is generated. :param _anchor: if provided this is added as anchor to the URL. + :param _method: if provided this explicitly specifies an HTTP method. """ ctx = _request_ctx_stack.top blueprint_name = request.blueprint @@ -211,8 +212,10 @@ def url_for(endpoint, **values): endpoint = endpoint[1:] external = values.pop('_external', False) anchor = values.pop('_anchor', None) + method = values.pop('_method', None) ctx.app.inject_url_defaults(endpoint, values) - rv = ctx.url_adapter.build(endpoint, values, force_external=external) + rv = ctx.url_adapter.build(endpoint, values, method=method, + force_external=external) if anchor is not None: rv += '#' + url_quote(anchor) return rv diff --git a/flask/testsuite/helpers.py b/flask/testsuite/helpers.py index 06b0542d..41e31be9 100644 --- a/flask/testsuite/helpers.py +++ b/flask/testsuite/helpers.py @@ -304,6 +304,32 @@ class LoggingTestCase(FlaskTestCase): self.assert_equal(flask.url_for('index', _anchor='x y'), '/#x%20y') + def test_url_with_method(self): + from flask.views import MethodView + app = flask.Flask(__name__) + class MyView(MethodView): + def get(self, id=None): + if id is None: + return 'List' + return 'Get %d' % id + def post(self): + return 'Create' + myview = MyView.as_view('myview') + app.add_url_rule('/myview/', methods=['GET'], + view_func=myview) + app.add_url_rule('/myview/', methods=['GET'], + view_func=myview) + app.add_url_rule('/myview/create', methods=['POST'], + view_func=myview) + + with app.test_request_context(): + self.assert_equal(flask.url_for('myview', _method='GET'), + '/myview/') + self.assert_equal(flask.url_for('myview', id=42, _method='GET'), + '/myview/42') + self.assert_equal(flask.url_for('myview', _method='POST'), + '/myview/create') + def suite(): suite = unittest.TestSuite()