现代 web 应用都使用有意义的 URL ,这样有助于用户记忆,网页会更得到用户的青睐, 提高回头率。

在Flask框架中,路由表示用户请求的URL找出其对应的处理函数。用户请求的URL与视图函数之间的映射,flask框架根据HTTP请求的URL在路由表中匹配预定义的URL规则, 找到对应的视图函数,并将函数执行的结果返回给服务器,route装饰器:绑定url规则与视图函数

1.装饰器route注册路由

在python中支持装饰器这种写法,通过装饰器注册路由是非常优雅的一种方式。

fisher.py

from flask import Flask

app = Flask(__name__)

@app.route('/hello')
def hello_world():
    return 'hello world!'

@app.route('/about')
def about():
  return 'about'

app.run()

我们通过Flask route来注册了两个路由,一个是/hello/about,通过http://localhost:5000/hellohttp://localhost:5000/about来访问视图函数。

2.手动注册路由

如果我们不route装饰器注册路由,在Flask核心对象中提供了一个app.add_url_rule方法来让我们手动注册路由。

fisher.py

from flask import Flask

app = Flask(__name__)

def hello_world():
    return 'hello world!'

def about():
  return 'about'

app.add_url_rule('/hello',view_func=hello_world)
app.add_url_rule('/about',view_func=about)

app.run()

注册完成后,重启服务,然后在通过访问http://localhost:5000/hellohttp://localhost:5000/about 来访问视图函数

3.路由参数

上面不管是通过装饰器route还是通过Flask核心对象add_url_rule()注册的路由都是静态路由。通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量。标记的 部分会作为关键字参数传递给函数。通过使用 <converter:variable_name> ,可以 选择性的加上一个转换器,为变量指定规则

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % escape(username)

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return 'Subpath %s' % escape(subpath)

转换器类型

类型描述
string(缺省值) 接受任何不包含斜杠的文本
int接受正整数
float接受正浮点数
path类似 string ,但可以包含斜杠
uuid接受 UUID 字符串

4.Flask中的route

在python 3.7入门教程中,小菜记录过一篇有关于python装饰器的文章,如果有小伙伴不是很了解装饰器请看装饰器。我们来分析下Flask中route做了件什么事情? 下面是Flask 中route的源码

...
@setupmethod
  def add_url_rule(
    self,
    rule,
    endpoint=None,
    view_func=None,
    provide_automatic_options=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

    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.

    .. 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 provide_automatic_options: controls whether the ``OPTIONS``
        method should be added automatically. This can also be controlled
        by setting the ``view_func.provide_automatic_options = False``
        before adding the rule.
    :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", 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",)
    if isinstance(methods, string_types):
        raise TypeError(
            "Allowed methods have to be iterables of strings, "
            'for example: @app.route(..., methods=["POST"])'
        )
    methods = set(item.upper() for item in 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.
    if provide_automatic_options is None:
        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

    rule = self.url_rule_class(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 route(self, rule, **options):
    """A decorator that is used to register a view function for a
    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'

    For more information refer to :ref:`url-route-registrations`.

    :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 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.
    """

    def decorator(f):
        endpoint = options.pop("endpoint", None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f

    return decorator
...

我们看到Flask route的构造器中只做了一件事,那就是调用add_url_rule方法。

Flask

Flask 准备工作(1) Flask URL(2) Flask 路由(3) Flask app.run参数(4) Flask 视图函数返回(5)