四、添加路由的两种方式

在Flask中,添加路由有两种方式:(一般情况下都是用第一种方式)

第一种:常见的装饰器模式

@app.route("/")
def index():
    return "Hello World"

通过这种方式,将rule与视图函数对应起来

第二种:通过阅读装饰器模式添加路由的源码发现

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

是通过self.add_url_rule这个方式建立起rule与视图函数的对应关系的,所以可以这样添加,

def home():
    return "Hello, home!"


app.add_url_rule("/home", endpoint=None, view_func=home)

endpoint:给rule起一个别名,相当于django path路由函数中的name。

如何使用通过别名(endpoint)找到rule呢?(如果不起别名,就默认为函数名)

@app.route("/", endpoint="index")
def index():
    return "Hello World"


def home():
    from flask import url_for
    r = url_for("index")
    # /
    print(r)
    return "Hello, home!"

===================================================================================================================================

如何通过路由传递参数呢?<转换器:参数名>

@app.route("/<int:uid>/", endpoint="index")
def index(uid):
    return "Hello {}".format(uid)

常用的转换器:int、float、path、uuid、string、any、default

不难发现,没有正则表达式的转换器,那么我们可以自定义:

 1 class RegexConverter(BaseConverter):
 2     def __init__(self, map, regex):
 3         super(RegexConverter, self).__init__(map)
 4         # 为什么只用赋值regex就可以了呢?其他转化器是在类属性regex(正则表达式)的基础上实现的
 5         self.regex = regex
 6 
 7     def to_python(self, value):
 8         """将提取后的值进行处理"""
 9         return value
10 
11     def to_url(self, value):
12         """用于反向解析url"""
13         val = super(RegexConverter, self).to_url(value)
14         return val
15 
16 
17 # 虽然我们已经定制好了正则转换器类,但是应用程序不知道,我们还要通知一下
18 app.url_map.converters["regex"] = RegexConverter
19 
20 
21 @app.route('/<regex("d+"):uid>/', endpoint="index")
22 def index(uid):
23     return "Hello {}".format(uid)

如何rule里面通过路由传参,那如何反向解析呢?

1 url_for(endpoint, **values)

参数通过**values传递:url_for(endpoint="index", uuid=10)

===================================================================================================================================

app.route方法常见的参数:

rule:URL规则

view_func:视图函数的名称

default:默认值,当URL中无参数,函数需要参数时,使用default={'k':'v'}为函数提供参数

endpoint:名称,用于反向生产URL,即:url_for('名称')

strict_slashes=None:对URL最后的/符号是否严格要求

redirect_to=None:重定向到指定地址

subdomain=None:子域名访问

==================================================================================================================================

路由重点:url、methods、endpoint、int转换器、url_for

==================================================================================================================================

如何给视图函数添加装饰器?

装饰器要放在app.route的下面(放在上面,只会执行一次),并且必须要保留被装饰函数的元信息,因为当我们使用一个装饰器去装饰多个函数时,不保留被装饰函数的元信息,endpoint会默认为函数名,这样就会都等于装饰器函数内部被返回的函数名,导致endpoint重名,会出现错误

 1 def showtime(func):
 2     def inner(uid):
 3         import time
 4         print(time.localtime())
 5         res = func(uid)
 6         print(time.localtime())
 7         return res
 8     return inner
 9 
10 
11 @app.route('/<regex("d+"):uid>/', endpoint="index")
12 @showtime
13 def index(uid):
14     return "Hello {}".format(uid)

为了保留被装饰函数的元信息,必须使用

 1 from functools import wraps
 2 
 3 
 4 def showtime(func):
 5     @wraps(func)
 6     def inner(uid):
 7         import time
 8         print(time.localtime())
 9         res = func(uid)
10         print(time.localtime())
11         return res
12     return inner
13 
14 
15 @app.route('/<regex("d+"):uid>/', endpoint="index")
16 @showtime
17 def index(uid):
18     return "Hello {}".format(uid)
原文地址:https://www.cnblogs.com/loveprogramme/p/13368483.html