def add_url_rule(self, rule, endpoint=None, view_func=None, **options): """Connects a URL rule. Works exactly like the :meth:`route` decorator. If a view_func is provided it will be registered with the endpoint. Basically this example:: @app.route('/') def index(): pass Is equivalent to the following:: def index(): pass 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 .. versionchanged:: 0.2 `view_func` parameter added. .. versionchanged:: 0.6 `OPTIONS` is added automatically as method. :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 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. """ if endpoint is None: endpoint = _endpoint_from_view_func(view_func) options['endpoint'] = endpoint methods = options.pop('methods', ('GET',)) provide_automatic_options = False if 'OPTIONS' not in methods: methods = tuple(methods) + ('OPTIONS',) provide_automatic_options = True rule = Rule(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule) if view_func is not None: self.view_functions[endpoint] = view_func
def add_url_rule(self, rule, endpoint=None, view_func=None, **options): """Connects a URL rule. Works exactly like the :meth:`route` decorator. If a view_func is provided it will be registered with the endpoint. Basically this example:: @app.route('/') def index(): pass Is equivalent to the following:: def index(): pass 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 .. versionchanged:: 0.2 `view_func` parameter added. .. versionchanged:: 0.6 `OPTIONS` is added automatically as method. :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 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. """ if endpoint is None: endpoint = _endpoint_from_view_func(view_func) options['endpoint'] = endpoint methods = options.pop('methods', ('GET', )) provide_automatic_options = False if 'OPTIONS' not in methods: methods = tuple(methods) + ('OPTIONS', ) provide_automatic_options = True rule = Rule(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule) if view_func is not None: self.view_functions[endpoint] = view_func
def add_url_rule(rule, endpoint=None, view_func=None, **options): if endpoint is None: endpoint = _endpoint_from_view_func(view_func) options['endpoint'] = endpoint methods = options.pop('methods', None) # if the methods are not given and the view_func object knows its # methods we can use that instead. If neither exists, we go with # a tuple of only `GET` as default. if methods is None: methods = getattr(view_func, 'methods', None) or ('GET',) methods = set(methods) # Methods that should always be added required_methods = set(getattr(view_func, 'required_methods', ())) # starting with Flask 0.8 the view_func object can disable and # force-enable the automatic options handling. provide_automatic_options = getattr(view_func, 'provide_automatic_options', None) if provide_automatic_options is None: if 'OPTIONS' not in methods: provide_automatic_options = True required_methods.add('OPTIONS') else: provide_automatic_options = False # Add the required methods now. methods |= required_methods # due to a werkzeug bug we need to make sure that the defaults are # None if they are an empty dictionary. This should not be necessary # with Werkzeug 0.7 options['defaults'] = options.get('defaults') or None rule = Rule(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options url_map.add(rule) if view_func is not None: old_func = view_functions.get(endpoint) if old_func is not None and old_func != view_func: raise AssertionError('View function mapping is overwriting an ' 'existing endpoint function: %s' % endpoint) view_functions[endpoint] = view_func
def add_url_rule(self, rule, endpoint=None, view_func=None, **options): assert view_func is not None, 'view_func is mandatory' if endpoint is None: endpoint = view_func.__name__ options['endpoint'] = endpoint # supposed to be GET methods = set(('GET', )) provide_automatic_options = False rule = Rule(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule) if view_func is not None: old_func = self.view_functions.get(endpoint) if old_func is not None and old_func != view_func: raise AssertionError('View function mapping is overwriting an ' 'existing endpoint function: %s' % endpoint) self.view_functions[endpoint] = view_func
def add_url_rule(self, rule, endpoint=None, view_func=None, **options): assert view_func is not None, 'view_func is mandatory' if endpoint is None: endpoint = view_func.__name__ options['endpoint'] = endpoint # supposed to be GET methods = set(('GET', )) provide_automatic_options = False rule = Rule(rule, methods=methods, **options) rule.provide_automatic_options = provide_automatic_options self.url_map.add(rule) if view_func is not None: old_func = self.view_functions.get(endpoint) if old_func is not None and old_func != view_func: raise AssertionError('View function mapping is overwriting an ' 'existing endpoint function: %s' % endpoint) self.view_functions[endpoint] = view_func
def __new__(cls, name, bases, attrs): # Add a url_map to the class url_map = UrlMap(strict_slashes=False) # Add a collection of (unbound) view functions view_functions = {} for base in bases: # Extend from url_map of base class if hasattr(base, 'url_map') and isinstance(base.url_map, UrlMap): for rule in base.url_map.iter_rules(): url_map.add(rule.empty()) # Extend from view_functions of base class if hasattr(base, 'view_functions') and isinstance(base.view_functions, dict): view_functions.update(base.view_functions) for routeattr, route in attrs.items(): if isinstance(route, _NodeRoute): # For wrapped routes, add a rule for each layer of wrapping endpoints = [] while isinstance(route, _NodeRoute): # Save the endpoint name endpoints.append(route.endpoint) # Construct the url rule url_rule = UrlRule(route.rule, endpoint=route.endpoint, methods=route.methods, defaults=route.defaults) url_rule.provide_automatic_options = True url_map.add(url_rule) route = route.f # Make a list of endpoints for e in endpoints: view_functions[e] = route # Restore the original function attrs[routeattr] = route # Finally, update the URL map and insert it into the class url_map.update() attrs['url_map'] = url_map attrs['view_functions'] = view_functions return type.__new__(cls, name, bases, attrs)