add_url_rule
类视图
标准视图
结合继承
基于调度方法的类视图
基于类视图使用装饰器
蓝图
蓝图的基本使用
蓝图下面的url_for
add_url_rule
add_url_rule方法,主要是手动像flask实例对象添加路径到处理函数的映射关系,它接收3个参数,第一个参数是访问的URI,第二个是这个URI的别名,主要是用户url_for,第三个的对应是处理函数;
from flask import Flask
app = Flask(__name__)
# 创建一个函数,返回一个字符串
def home():
return 'cce'
app.add_url_rule('/', endpoint='home',view_func=home) # 在这里将uri到处理函数的映射关系添加到flask对象
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
类视图
之前接触的都是函数视图,所以一般简称视图函数,其实视图也可以基于类来实现,类视图的好处是支持继承,但是类视图不能跟函数视图一样,写完类视图需要通过app.add_url_rule来注册类视图;
类视图的好处,可以继承把一些共性的东西抽取出来放到父级视图中;
标准视图
标准视图继承自flask.views.View,并且在子类中必须实现dispatch_request方法,这个方法类似于视图函数,也要返回一个基于Response或者其子类对象。
app = Flask(__name__)
class Home(View):
def dispatch_request(self): # 不论是GET还是POST方法都会都dispatch_request
return '1'
app.add_url_rule('/',view_func=Home.as_view('home')) # as_view将类视图转换为函数视图,他底层还是调用的dispatch_request函数,里面需要传入一个参数,也就是我们的endpoint;
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
结合继承
结合继承的好处案例一,当有类视图最终返回的都是一个json数据,那么我们就可以通过继承来简洁代码;
from flask import Flask, jsonify
from flask.views import View
app = Flask(__name__)
class JsonView(View):
def get_json_data(self):
raise NotImplementedError # 如果子类中没有定义get_json_data那么就抛出异常
def dispatch_request(self): # 因为类视图都需要调用dispatch_request所以直接在父级类里面加入dispatch_request,那么在继承该类的类视图就不需要定义dispatch_request
return jsonify(self.get_json_data()) # 此处的self.get_json_data调用的实际上是继承这个类的子类中的方法
class Home(JsonView):
def get_json_data(self): # 因为父类JsonView中有dispatch_request那么子类就不需要实现dispatch_request
return {'name': 'cce'}
app.add_url_rule('/', view_func=Home.as_view('home')) # as_view将类视图转换为函数视图,里面需要传入一个参数,也就是我们的endpoint;
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
基于调度方法的类视图
Flask还为我们提供了另一种类视图flask.views.MethodView,对每个http方法执行不同的类视图的方法,这对Restful API尤其有用;
from flask import Flask
from flask.views import MethodView
app = Flask(__name__)
class Home(MethodView):
def get(self):
return 'get'
def post(self):
return 'pos'
app.add_url_rule('/', view_func=Home.as_view('home')) # as_view将类视图转换为函数视图,里面需要传入一个参数,也就是我们的endpoint;
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
基于类视图使用装饰器
Flask已经考虑好了,我们只需要在自定义的类视图里面加入一个类属性decorators并且指明使用的装饰器即可;
对于methods和装饰器也是一样的,可以直接在类属性里面添加一个methods类属性指明支持的请求方法;
from flask import Flask, request, Response
from functools import wraps
from flask.views import View
app = Flask(__name__)
def login_required(func):
@wraps(func)
def wapper(*args, **kwargs):
if request.args.get('username', None):
return func(*args, **kwargs)
else:
return '你没有携带必要的参数'
return wapper
class Home(View):
decorators = [login_required] # 指明装饰器
methods = ['GET','POST'] # 指明允许请求的方法
def dispatch_request(self):
return 'cce'
app.add_url_rule('/', view_func=Home.as_view('home'))
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
蓝图
Blueprint,和Django中的app的概恋是差不多的,随着flask程序越来越复杂,我们需要对程序进行分层解耦,模块化的处理,比如只有一个run.py。有些功能需要多人分开来写,有些功能会有交错的可能,代码位置也不会在一起,这样可以用蓝图来开关一些模块(功能)和宏定义类似,但不是可插拔的应用而是一套可以注册在应用中的操作,并且可以注册多次。或者简单滴需要降低耦合,提高模块复用率。比如开发环境和应用环境的不同,可以用蓝图来切换环境。
url_prefix:定义蓝图的访问前缀,记住这里不要用/结尾;
其他的配置和创建flask实例的配置差不多;
蓝图的基本使用
# 目录层级结构
[root@Linux ~/edu]# tree
.
├── main.py
├── UserModel
│ ├── __init__.py
│ └── user.py
└── VideoModel
├── __init__.py
└── video.py
# main.py
from flask import Flask
from UserModel.user import User
from VideoModel.video import Video
app = Flask(__name__)
app.register_blueprint(User)
app.register_blueprint(Video)
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
# user.py
from flask import Blueprint
User=Blueprint('user',__name__, url_prefix='/user') # 第一个参数为蓝图的名字
@User.route('/')
def home():
return 'UserModel'
# video.py
from flask import Blueprint
Video = Blueprint('video', __name__, url_prefix='/video') # 第一个参数为蓝图的名字
@Video.route('/')
def home():
return 'VideoModel'
蓝图下面的url_for
当我们使用了蓝图之后,我们在主入口文件比如我们的main.py里面想要拿到蓝图里面的url_for,直接使用函数的名字那可能有点问题,那么我们需要找他,在取值的时候需要跟上Blueprnt的名字;
# 目录层级结构
[root@Linux ~/edu]# tree
.
├── main.py
├── UserModel
│ ├── __init__.py
│ └── user.py
└── VideoModel
├── __init__.py
└── video.py
# main.py
from flask import Flask,url_for
from UserModel.user import User
from VideoModel.video import Video
app = Flask(__name__)
app.register_blueprint(User)
app.register_blueprint(Video)
@app.route('/')
def home():
print(url_for('user.userhome')) # user是蓝图的名字,userhome是函数的名字
return '这是首页'
if __name__ == '__main__':
app.run("0.0.0.0", port=80, debug=True)
# user.py
from flask import Blueprint
User=Blueprint('user',__name__, url_prefix='/user')
@User.route('/')
def userhome():
return 'UserModel'
# video.py
from flask import Blueprint
Video = Blueprint('video', __name__, url_prefix='/video')
@Video.route('/')
def videohome():
return 'VideoModel'
本文暂时没有评论,来添加一个吧(●'◡'●)