ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

flask教程之路由

2020-11-09 15:33:16  阅读:217  来源: 互联网

标签:教程 return flask app def 视图 url rule 路由


1. app.add_url_rule()函数

在flask中,我们知道给一个函数添加url的时候,只需要使用装饰器@app.route('<url>')装饰对应的函数就可以了。为什么这个装饰器就可以给函数视图 添加url规则呢?查看app.route()源码发现,这个装饰器在里面调用的另外一个方法self.add_url_rule,这里的self就是app这个实例对象。

app.route()源码内容

def route(self, rule, **options):
	def decorator(f):
	    endpoint = options.pop("endpoint", None)
	    self.add_url_rule(rule, endpoint, f, **options)
	    return f
	
	return decorator
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

那么app.route这个装饰器就是通过调用add_url_rule这个方法生成函数视图对应的url的,那么我们可不可以我们自己直接调用这个方法来生成函数对应的url规则呢?答案是肯定的。

示例如下:

from flask import Flask

app = Flask(__name__)

def index():
	return 'index'

app.add_url_rule('/index/',endpoint='index',view_func=index)
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

add_url_rule三个参数解释:

  • 第一个参数:函数对应的url规则,满足条件和app.route()的第一个参数一样,必须以'/'开始
  • endpoint:站点,就是在使用url_for()进行反转的时候,这个里面传入的第一个参数就是这个endpoint对应的值。这个值也可以不指定,那么默认就会使用函数的名字作为endpoint的值
  • view_func:对应的函数,即这个url对应的是哪一个函数,注意,这里函数只需要写函数名字,不要加括号,加括号表示将函数的返回值传给了view_func参数了。程序就会直接报错。
# 正确的方式
app.add_url_rule('/index/',endpoint='index',view_func=index)
# 错误的方式
app.add_url_rule('/index/',endpoint='index',view_func=index())
 
  • 1
  • 2
  • 3
  • 4
  • methods:add_url_rule还可以传入一个methods参数,用来指定这个函数对应的访问规制,如post,get请求等,默认是get请求,并且只允许get请求。当我们需要改变请求方式的时候,我们就可以传入这个参数了。
# 指定一种
app.add_url_rule('/index/',endpoint='index',view_func=index,methods=['POST'])
# 指定多种
app.add_url_rule('/index/',endpoint='index',view_func=index,methods=['POST','get'])
 
  • 1
  • 2
  • 3
  • 4

注意:

  • 就算是只指定一种请求方式,也必须的用列表或元祖包裹起来,最好是用列表,元祖在某些情况下可能会出错。
  • 当元祖里面只有一个值得时候,后面必须的加一个,('post',)

2. 什么是类视图

我们知道,在flask中,我们写的视图都是以函数形式写的,所以一般简称函数视图。其实视图我们也可以使用类来实现,类视图的好处是支持继承,但是类视图不能跟函数视图一样,写完类视图之后,我们还需要通过app.add_url_rule( url_rule, view_func )来进行注册。在flask中,有两种类视图。

3. 标准类视图

标准类视图是继承自flask.views.View,并且在子类中必须实现dispatch_request方法,这个方法就是相当于视图函数,所有的逻辑操作我们都要放在这个里面完成。也必须的返回一个值,函数视图能返回什么类型的值,这里就可以返回什么类型的值。其实类视图和函数视图基本都是一样的,只是我们在做添加url规则的时候不一样而已。

from flask import Flask,views

app = Flask(__name__)

class ProfileView(views.View):

    def dispatch_request(self):
        return '个人中心页面'

app.add_url_rule('/profile/',endpoint='profile',view_func=ProfileView.as_view('profile'))
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

add_url_rule里面的参数的意思相信大家也知道了,这里说一下as_view里面传入的参数的意思吧。

  • View.as_view(’<指定函数的名称>’):因为我们所以的类视图都会继承自View类,并且都要重写dispatch_request方法,那么flask怎么知道我们绑定的是哪一个类的dispatch_request方法呢?就是通过这个参数来指定的。相当于给我们的dispatch_request方法起一个名字。当我们没有写endpoint参数的时候,那么endpoint的值就会是我们这个函数的名字。通过url_for进行反转的时候也是用的这个值。如果指定了endpoint的值,url_for就会使用endpoint的值,我们指定的函数名称对于我们来说没有什么太大的用处了,但是flask内部还是很有用处的。

4. 基于调度方法的视图

在flask中,还提供了另外一种类视图flask.views.MethodView,对每个HTTP的请求方法执行不同的函数,映射到对应小写的同名方法上面。例如:

class LoginView(views.MethodView):
    def get(self):
        return 'get 请求'

    def post(self):
        return 'post 请求'
        
app.add_url_rule('/login/',view_func=LoginView.as_view('login'))
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样,当我们以GET请求访问/login/页面的时候,就会执行get方法,以POST请求访问/login/页面的时候,就会执行post方法。

比如我们登陆的时候,如果用户使用的是get方法请求我们的页面,那么我们就渲染一个html页面给客户端,而当使用post方法请求的时候,我们就对上传的数据进行处理,然后返回相应的信息。

5. 视图使用装饰器

假设我们现在有一个需求:如果用户请求的时候以get请求传入了username参数,我们就认为登陆了(模拟登陆的效果。),可以访问个人中心页面,否则的话就认为没有登陆。重定向到登陆页面。

这种需求我们一把都不会在视图中的逻辑代码中判断,而会定义一个装饰器。

  1. 定义装饰器:
from flask import Flask,views,request,redirect,url_for
from functools import wraps

app = Flask(__name__)

def login_require(fn):
    @wraps(fn)
    def wrapper(*args,**kwargs):
        username = request.args.get('username')
        if username and username == 'xxx':
            return fn(*args,**kwargs)
        else:
            return redirect( url_for('login') )
    return wrapper
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 函数视图使用装饰器。

上面我们就把装饰器定义好了,接下里我们就要开始使用这个装饰器了

@app.route('/login/')
def login():
	return 'login page'

@app.route('/profile/')
@login_require		# 使用我们写的login_require装饰器 这个装饰器必须放在@app.route()装饰器的下面
def profile():
	return '个人中心'
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样,我们就对我们的profile这个视图进行了装饰,如果输入网址为127.0.0.1:5000/profile/的时候,就会重定向到login视图中去。如果输入网址为127.0.0.1:5000/profile/?username=xxx才会被允许进入profile视图。当然,这里只是假设认为传入了username参数并且等于xxx就认为登陆了,在项目中肯定不会这样写的。在这里我们也只是为了知道装饰器的使用而已。

注意:

  • 如果我们使用app.route添加url规则的话,那么我们自己写的装饰器就必须放在app.route的下面。否则的话我们写的装饰器是没有作用的
  • 如果有多个装饰器的话。每个装饰器都必须放在app.route下面,然后就可以随便放置了。
  1. 类视图使用装饰器
  • 使用views.View方法
class ProfileView(views.View):
	# 将这个视图所有的装饰器用decorators这个列表装起来
	decorators = [login_require]

	def dispatch_request(self):
		return '个人中心页面'

# 当然也可以直接装饰这个函数
class ProfileView(views.View):
	@login_require	
	def dispatch_request(self):
		return '个人中心页面'

app.add_url_rule('/profile/',view_func=Profile.as_view('profile'))
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

上面的两种方式都是可以的,至于用哪一种就看心情吧

  • 使用views.MethodView类

MethodView有三种方法进行装饰。

# 第一种,直接对相应的请求进行装饰
class ProfileView(views.MethodView):
	@login_require
	def get(self):
		return 'profile from get method'

	def post(self):
		return 'profile from post method'

# 第二种,重写dispatch_request方法,然后进行装饰
class ProfileView(views.MethodView):
	@login_require
	def dispatch_request(self,*args,**kwargs):
		return super().dispatch_request(*args,**kwargs)
		
	def get(self):
		return 'profile from get method'

	def post(self):
		return 'profile from post method'

# 第三中,使用decorators属性
class ProfileView(views.MethodView):
	decorators = [login_require]
		
	def get(self):
		return 'profile from get method'

	def post(self):
		return 'profile from post method'

app.add_url_rule('/profile/',view_func=Profile.as_view('profile'))
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

三种方式向使用哪一种都可以,看自己心情吧

标签:教程,return,flask,app,def,视图,url,rule,路由
来源: https://www.cnblogs.com/haoyuheng/p/13948777.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有