From df1dd57045b38ea7dcca44622744ab24e53e399e Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sun, 25 Sep 2011 18:49:00 +0200 Subject: [PATCH] Cleaned up url routing common docs. This fixes #279 --- docs/api.rst | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++ flask/app.py | 76 +++++++++------------------------------- 2 files changed, 114 insertions(+), 59 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index aca7fda5..5e5082bf 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -478,6 +478,103 @@ Class Based Views .. autoclass:: flask.views.MethodView :members: +.. _url-route-registrations: + +URL Route Registrations +----------------------- + +Generally there are three ways to define rules for the routing system: + +1. You can use the :meth:`flask.Flask.route` decorator. +2. You can use the :meth:`flask.Flask.add_url_rule` function. +3. You can directly access the underlying Werkzeug routing system + which is exposed as :attr:`flask.Flask.url_map`. + +Variables parts in the route can be specified with angular brackets +(``/user/``). By default a variable part in the URL accepts any +string without a slash however a different converter can be specified as +well by using ````. + +Variable parts are passed to the view function as keyword arguments. + +The following converters are possible available: + +=========== =============================================== +`unicode` accepts any text without a slash (the default) +`int` accepts integers +`float` like `int` but for floating point values +`path` like the default but also accepts slashes +=========== =============================================== + +Here some examples:: + + @app.route('/') + def index(): + pass + + @app.route('/') + def show_user(username): + pass + + @app.route('/post/') + def show_post(post_id): + pass + +An important detail to keep in mind is how Flask deals with trailing +slashes. The idea is to keep each URL unique so the following rules +apply: + +1. If a rule ends with a slash and is requested without a slash by the + user, the user is automatically redirected to the same page with a + trailing slash attached. +2. If a rule does not end with a trailing slash and the user request the + page with a trailing slash, a 404 not found is raised. + +This is consistent with how web servers deal with static files. This +also makes it possible to use relative link targets safely. + +You can also define multiple rules for the same function. They have to be +unique however. Defaults can also be specified. Here for example is a +definition for a URL that accepts an optional page:: + + @app.route('/users/', defaults={'page': 1}) + @app.route('/users/page/') + def show_users(page): + pass + +This specifies that ``/users/`` will be the URL for page one and +``/users/page/N`` will be the URL for page `N`. + +Here the parameters that :meth:`~flask.Flask.route` and +:meth:`~flask.Flask.add_url_rule` accept. The only difference is that +with the route parameter the view function is defined with the decorator +instead of the `view_func` parameter. + +=============== ========================================================== +`rule` the URL roule as string +`endpoint` the endpoint for the registered URL rule. Flask itself + assumes that the name of the view function is the name + of the endpoint if not explicitly stated. +`view_func` the function to call when serving a request to the + provided endpoint. If this is not provided one can + specify the function later by storing it in the + :attr:`~flask.Flask.view_functions` dictionary with the + endpoint as key. +`defaults` A dictionary with defaults for this rule. See the + example above for how defaults work. +`subdomain` specifies the rule for the subdomain in case subdomain + matching is in use. If not specified the default + subdomain is assumed. +`**options` the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change to + Werkzeug is handling of method options. methods is a list + of methods this rule should be limited to (`GET`, `POST` + etc.). By default a rule just listens for `GET` (and + implicitly `HEAD`). Starting with Flask 0.6, `OPTIONS` is + implicitly added and handled by the standard request + handling. They have to be specified as keyword arguments. +=============== ========================================================== + .. _view-func-options: View Function Options diff --git a/flask/app.py b/flask/app.py index adc017d0..91ea3414 100644 --- a/flask/app.py +++ b/flask/app.py @@ -824,9 +824,11 @@ class Flask(_PackageBoundObject): app.view_functions['index'] = index - If a view function is provided some defaults can be specified directly - on the view function. For more information refer to - :ref:`view-func-options`. + Internally :meth:`route` invokes :meth:`add_url_rule` so if you want + to customize the behavior via subclassing you only need to change + this method. + + For more information refer to :ref:`url-route-registrations`. .. versionchanged:: 0.2 `view_func` parameter added. @@ -885,73 +887,29 @@ class Flask(_PackageBoundObject): def route(self, rule, **options): """A decorator that is used to register a view function for a - given URL rule. Example:: + given URL rule. This does the same thing as :meth:`add_url_rule` + but is intended for decorator usage:: @app.route('/') def index(): return 'Hello World' - Variables parts in the route can be specified with angular - brackets (``/user/``). By default a variable part - in the URL accepts any string without a slash however a different - converter can be specified as well by using ````. - - Variable parts are passed to the view function as keyword - arguments. - - The following converters are possible: - - =========== =========================================== - `int` accepts integers - `float` like `int` but for floating point values - `path` like the default but also accepts slashes - =========== =========================================== - - Here some examples:: - - @app.route('/') - def index(): - pass - - @app.route('/') - def show_user(username): - pass - - @app.route('/post/') - def show_post(post_id): - pass - - An important detail to keep in mind is how Flask deals with trailing - slashes. The idea is to keep each URL unique so the following rules - apply: - - 1. If a rule ends with a slash and is requested without a slash - by the user, the user is automatically redirected to the same - page with a trailing slash attached. - 2. If a rule does not end with a trailing slash and the user request - the page with a trailing slash, a 404 not found is raised. - - This is consistent with how web servers deal with static files. This - also makes it possible to use relative link targets safely. - - The :meth:`route` decorator accepts a couple of other arguments - as well: + For more information refer to :ref:`url-route-registrations`. :param rule: the URL rule as string - :param methods: a list of methods this rule should be limited + :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 serving a request to the + provided endpoint + :param options: the options to be forwarded to the underlying + :class:`~werkzeug.routing.Rule` object. A change + to Werkzeug is handling of method options. methods + is a list of methods this rule should be limited to (`GET`, `POST` etc.). By default a rule just listens for `GET` (and implicitly `HEAD`). Starting with Flask 0.6, `OPTIONS` is implicitly added and handled by the standard request handling. - :param subdomain: specifies the rule for the subdomain in case - subdomain matching is in use. - :param strict_slashes: can be used to disable the strict slashes - setting for this rule. See above. - :param endpoint: Since version 0.8 you can also pass the enpoint, - it will be used instead of generating the endpoint - from the function name. - :param options: other options to be forwarded to the underlying - :class:`~werkzeug.routing.Rule` object. """ def decorator(f): endpoint = options.pop('endpoint', None)