Flask系列教程(5)——视图高级
来源:互联网 发布:latex for mac 编辑:程序博客网 时间:2024/06/06 05:29
flask入门(视图高级)
类视图:
之前我们接触的视图都是函数,所以一般简称视图函数。其实视图也可以基于类来实现,类视图的好处是支持继承,但是类视图不能跟函数视图一样,写完类视图还需要通过app.add_url_rule(url_rule,view_func)
来进行注册。以下将对两种类视图进行讲解:
标准视图:
标准视图继承自flask.views.View
,并且在子类中必须实现dispatch_request
方法,这个方法类似于视图函数,也要返回一个基于Response
或者其子类的对象。以下将用一个例子进行讲解:
class BaseView(views.View): # 自定义方法,用来获取模板路径 def get_template_name(self): raise NotImplementedError() # 必须实现的方法,用来处理请求的 def dispatch_request(self): if request.method != 'GET': return 'method error' #这里从self.get_data()中获取数据,子类应该实现这个方法 context = {'data':self.get_data()} return render_template(self.get_template_name(),**context)class UserView(BaseView): # 实现从父类继承的获取模板路径的方法 def get_template_name(self): return 'user.html'# 重写获取数据的方法def get_data(self): return [{ 'username': 'fake', 'avatar': 'http://www.baidu.com/' }]# 类视图通过add_url_rule方法和url做映射app.add_url_rule('/users/',view_func=UserView.as_view('userview'))
基于调度方法的视图:
Flask
还为我们提供了另外一种类视图flask.views.MethodView
,对每个HTTP方法执行不同的函数(映射到对应方法的小写的同名方法上),这对RESTful API
尤其有用,以下将用一个例子来进行讲解:
class UserAPI(views.MethodView): # 当客户端通过get方法进行访问的时候执行的函数 def get(self): return jsonify({ 'username':'xiaotuo', 'avatar':'http://www.baidu.com/' }) # 当客户端通过post方法进行访问的时候执行的函数 def post(self): return 'UNSUPPORTED!'# 通过add_url_rule添加类视图和url的映射,并且在as_view方法中指定该url的名称,方便url_for函数调用app.add_url_rule('/myuser/',view_func=UserAPI.as_view('userapiview'))
用类视图的一个缺陷就是比较难用装饰器来装饰,比如有时候需要做权限验证的时候,比如看以下例子:
def user_required(f): def decorator(*args,**kwargs): if not g.user: return 'auth failure' return f(*args,**kwargs) return decorator
如果要在类视图上进行装饰,只能在as_view
函数上进行装饰了,使用方式如下:
view = user_required(UserAPI.as_view('users'))app.add_url_rule('/users/',view_func=view)
但是一个好消息是,从Flask 0.8
开始,还可以通过在类中添加decorators
属性来实现对视图的装饰:
class UserAPI(views.MethodView):decorators = [user_required]...
蓝图(blueprint):
之前我们写的url
和视图函数都是处在同一个文件,如果项目比较大的话,这显然不是一个合理的结构,而蓝图可以优雅的帮我们实现这种需求。使用蓝图一般是将相同的URL
前缀,比如/user/:id
、/user/profile/
这样的地址,他们的特点都是以user
开头的,那么可以将这一类的url
放在一个模块中,达到项目的模块化,以下看一个使用蓝图的文件的例子(user.py):
from flask import Blueprintbp = Blueprint('user',__name__,url_prefix='/user/')@bp.route('/')def index(): return "User's Index Page"@bp.route('/profile/')def profile(): return "User's profile Page"
然后我们在主程序中,通过app.register_blueprint()
方法将这个蓝图注册进url映射中,看下主app
的实现:
from flask import Flaskimport userapp = Flask(__name__)app.register_blueprint(user.bp)if __name__ == '__main__': app.run(host='0.0.0.0',port=9000)
以后访问/user/
,/user/profile/
,都是执行的user.py
文件中的视图函数,这样就实现了项目的模块化。
以上是对蓝图的一个简单介绍,但是使用蓝图还有几个需要注意的地方,就是在蓝图如何寻找静态文件、模板文件,url_for
函数如何反转url
,以下分别进行解释:
- 寻找静态文件:默认不设置任何静态文件路径,
Jinja2
会在项目的static
文件夹中寻找静态文件。也可以设置其他的路径,在初始化蓝图的时候,Blueprint
这个构造函数,有一个参数static_folder
可以指定静态文件的路径,如:
bp = Blueprint('admin',__name__,url_prefix='/admin',static_folder='static')
static_folder
可以是相对路径(相对蓝图文件所在的目录),也可以是绝对路径。在配置完蓝图后,还有一个需要注意的地方是如何在模板中引用静态文件。在模板中引用蓝图,应该要使用蓝图名+.+static
来引用,如下所示:
<link href="{{ url_for('admin.static',filename='about.css') }}">
- 寻找模板文件:跟静态文件一样,默认不设置任何模板文件的路径,将会在项目的
templates
中寻找模板文件。也可以设置其他的路径,在构造函数Blueprint
中有一个template_folder
参数可以设置模板的路径,如下所示:
bp = Blueprint('admin',__name__,url_prefix='/admin',template_folder='templates')
模板文件和静态文件有点区别,以上代码写完以后,如果你渲染一个模板return render_template('admin.html')
,Flask
默认会去项目根目录下的templates
文件夹中查找admin.html
文件,如果找到了就直接返回,如果没有找到,才会去蓝图文件所在的目录下的templates
文件夹中寻找。
url_for
生成url
:用url_for
生成蓝图的url
,使用的格式是:蓝图名称+.+视图函数名称
。比如要获取admin
这个蓝图下的index
视图函数的url
,应该采用以下方式:
url_for('admin.index')
其中这个蓝图名称是在创建蓝图的时候,传入的第一个参数。bp = Blueprint('admin',__name__,url_prefix='/admin',template_folder='templates')
子域名:
子域名在许多网站中都用到了,比如一个网站叫做xxx.com
,那么我们可以定义一个子域名cms.xxx.com
来作为cms
管理系统的网址,子域名的实现一般也是通过蓝图来实现,在之前章节中,我们创建蓝图的时候添加了一个url_prefix=/user
作为url前缀,那样我们就可以通过/user/
来访问user
下的url。但使用子域名则不需要。另外,还需要配置SERVER_NAME
,比如app.config[SERVER_NAME]='example.com:9000'
。并且在注册蓝图的时候,还需要添加一个subdomain
的参数,这个参数就是子域名的名称,先来看一下蓝图的实现(admin.py):
from flask import Blueprintbp = Blueprint('admin',__name__,subdomain='admin')@bp.route('/')def admin(): return 'Admin Page'
这个没有多大区别,接下来看主app
的实现:
from flask import Flaskimport admin# 配置`SERVER_NAME`app.config['SERVER_NAME'] = 'example.com:8000'# 注册蓝图,指定了subdomainapp.register_blueprint(admin.bp)if __name__ == '__main__': app.run(host='0.0.0.0',port=8000,debug=True)
写完以上两个文件后,还是不能正常的访问admin.example.com:8000
这个子域名,因为我们没有在host
文件中添加域名解析,你可以在最后添加一行127.0.0.1 admin.example.com
,就可以访问到了。另外,子域名不能在127.0.0.1
上出现,也不能在localhost
上出现。
对Python和Flask感兴趣,可以加群:526929231一起讨论和学习哦。
- Flask系列教程(5)——视图高级
- Flask系列教程(2)——URL和视图
- Flask系列教程(7)——Flask-Script
- Flask系列教程(8)——Flask-Migrate
- Flask系列教程(9)——Flask-WTF
- Flask系列教程(1)——认识web
- Flask系列教程(3)——Jinja2模板
- Flask系列教程(4)——SQLAlchemy数据库
- Flask系列教程(10)——上下文
- Flask系列教程(11)——cookie和session
- Flask系列教程(三)---------------通过模板创建视图(一)
- Flask系列教程(一)-----------入门
- 用flask开发个人博客(3)—— flask中的请求和视图函数映射
- SQL VIEW(视图) 高级教程
- SQL VIEW(视图) 高级教程
- Flask系列教程(二)--------------使用SQLAlchemy创建数据模型
- 微信小程序视图层的数据绑定 —— 微信小程序教程系列(9)
- 微信小程序视图层的列表渲染 —— 微信小程序教程系列(11)
- 依云工资查询系统升级至6.4
- 活动安排(贪心算法)
- Java相对路径读取文件
- 无数个骂娘的故事告诉你,千万别做技术合伙人
- js oc 交互 加载沙盒路径下的图片
- Flask系列教程(5)——视图高级
- git学习之远程仓库
- orc
- [BZOJ1001]-狼抓兔子 Dinic模板题
- Linux初学者必知的5个学习网站
- 关于freeswitch1.5在ubuntu14.04上安装遇到的问题1
- python编程快速上手--重点整理(上)
- github生产SSH和查看相应的SSH
- 转下需要经常看看的磁盘知识,来自大众点评技术博客