Flask框架 之 路由和视图详解

路由+视图

我们之前了解了路由系统是由带参数的装饰器完成的。

路由本质:装饰器和闭包实现的。

路由设置的两种方式

来看个例子。

@app.route('/index')
def index():

    return "index"

我们之前用的装饰器都是不带参数的,执行的时候直接是将函数名作为参数传给装饰器执行。那么带参数的装饰器时如何执行的呢?

我们看一下源码:先从route点进去。

先去掉@执行

得到这样的结果。

我们可以将这个带参数的装饰器分开执行。

1. 先执行 decorator = app.route('/index')   
2. @decorator  

 将函数名组委参数传给装饰器@decorator.

最后我们发现,以上带参数的装饰器最后也可以写成:

def index():
    return "index"

app.add_url_rule("/index",None,index)  

这就是Flask路由设置的两种方式。 

注意事项:

  • 不要让endpoint重名
  • 如果非要重名,必须要保证函数是同一个函数,两个函数同名也不行。

参数

 @app.route和app.add_url_rule参数:
            rule,                       URL规则
            view_func,                  视图函数名称
            defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
            endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
            methods=None,               允许的请求方式,如:["GET","POST"]
            

            strict_slashes=None,        对URL最后的 / 符号是否严格要求,
                                        如:
                                            @app.route('/index',strict_slashes=False),
                                                访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
                                            @app.route('/index',strict_slashes=True)
                                                仅访问 http://www.xx.com/index 
            redirect_to=None,           重定向到指定地址
                                        如:
                                            @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
                                            或
                                            def func(adapter, nid):
                                                return "/home/888"
                                            @app.route('/index/<int:nid>', redirect_to=func)
            subdomain=None,             子域名访问
                                                from flask import Flask, views, url_for

                                                app = Flask(import_name=__name__)
                                                app.config['SERVER_NAME'] = 'wupeiqi.com:5000'


                                                @app.route("/", subdomain="admin")
                                                def static_index():
                                                    """Flask supports static subdomains
                                                    This is available at static.your-domain.tld"""
                                                    return "static.your-domain.tld"


                                                @app.route("/dynamic", subdomain="<username>")
                                                def username_index(username):
                                                    """Dynamic subdomains are also supported
                                                    Try going to user1.your-domain.tld/dynamic"""
                                                    return username + ".your-domain.tld"


                                                if __name__ == '__main__':
                                                    app.run()

CBV

通过dispatch_request  

import functools
from flask import Flask,views
app = Flask(__name__)


def wrapper(func):
	@functools.wraps(func)
	def inner(*args,**kwargs):
		return func(*args,**kwargs)

	return inner



class UserView(views.MethodView):
	methods = ['GET']             #方法
	decorators = [wrapper,]     #装饰器

	def get(self,*args,**kwargs):
		return 'GET'

	def post(self,*args,**kwargs):
		return 'POST'

app.add_url_rule('/user',None,UserView.as_view('uuuu'))

if __name__ == '__main__':
	app.run()

自定义正则

路由管理中没有正则匹配,但是我们可以自定义正则匹配。 

from flask import Flask,url_for

app = Flask(__name__)

# 步骤一:定制类
from werkzeug.routing import BaseConverter
class RegexConverter(BaseConverter):
	"""
	自定义URL匹配正则表达式
	"""

	def __init__(self, map, regex):
		super(RegexConverter, self).__init__(map)
		self.regex = regex

	def to_python(self, value):
		"""
		路由匹配时,匹配成功后传递给视图函数中参数的值
		:param value:
		:return:
		"""
		return int(value)

	def to_url(self, value):
		"""
		使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
		:param value:
		:return:
		"""
		val = super(RegexConverter, self).to_url(value)
		return val

# 步骤二:添加到转换器
app.url_map.converters['reg'] = RegexConverter

"""
1. 用户发送请求
2. flask内部进行正则匹配
3. 调用to_python(正则匹配的结果)方法
4. to_python方法的返回值会交给视图函数的参数

"""

# 步骤三:使用自定义正则
@app.route('/index/<reg("\d+"):nid>')
def index(nid):
	print(nid,type(nid))

	print(url_for('index',nid=987))
	return "index"

if __name__ == '__main__':
	app.run()

  

 

posted @ 2018-06-23 20:01  高~雅  阅读(1382)  评论(0编辑  收藏  举报