Flask中的视图函数以及视图类:

添加视图函数还可以通过下面的方式add_url_rule进行:

app.add_url_rule(rule,  endpoint,  view_func):

rule:  对应的url

endpoint:相当于给url取一个名字

view_func:视图函数

-------------------------------------------------------------------------------------------------------------------------------
endpoint用于反转视图函数得到url,如果给endpoint赋了值,那么在使用url_for()获取视图函数的url时,就不能再使用函数名作为参数,而是应该使用endpoint来获取视图函数的url

from flask import Flask, url_forapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():print(url_for("theList"))   # 这里url_for的参数值只能是theList, 不能是my_list return 'Hello World!'def my_list():return "This is item list"app.add_url_rule(rule="/list/", endpoint="theList", view_func=my_list)if __name__ == '__main__':app.run(debug=True)

标准类视图及其使用场景:

如何将类变成一个视图函数:类视图支持继承,写完类视图,需要通过add_url_rule进行添加

1. 标准类视图:

标准类视图继承自flask.views.View,并且在子类中必须实现dispatch_request方法,这个方法类似于视图函数,也要返回一个基于Response或者其子类的对象.

from flask import Flask, url_for, viewsapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():return 'Hello World!'class ListView(views.View):def dispatch_request(self):"""类视图中必须实现这一个方法:return:"""return "This is list view"app.add_url_rule(rule="/list/", endpoint="list", view_func=ListView.as_view("list"))
# 这里的as_view会将一个对象转化为函数,赋值给视图函数, 参数name是给转换后的函数取的名字if __name__ == '__main__':app.run(debug=True)

如果制定了endpoint,那么在使用url_for时必须使用endpoint, 如果没有指定,那么就可以使用as_view中的名字。

类试图的应用:

a. 例如有url需要返回字典

from flask import Flask, views, jsonifyapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():return 'Hello World!'class JsonView(views.View):    # 定义基类def get_data(self):return NotImplementedErrordef dispatch_request(self):return jsonify(self.get_data())class ListView(JsonView):def get_data(self):return {"username": "Tom", "password": "2345"}app.add_url_rule(rule="/list/", endpoint="list", view_func=ListView.as_view("list"))
# 这里的as_view会将一个对象转化为函数,赋值给视图函数, 参数name是给转换后的函数取的名字if __name__ == '__main__':app.run(debug=True)

JsonView类是基类,定义get_data()方法,ListView类是JsonView类的基类,在基类中,重新实现了get_data()方法,在调用ListView中的dispatch_request()方法的时候,由于ListView中未重写dispatch_request()方法,所以回去调用父类中的dispatch_request()方法,在父类的dispatch_request()方法中会调用get_data()方法,而在子类ListView中实现了get_data方法,所以实际调用的是子类ListView中的方法,返回字典

b. 有几个url需要返回相同的变量:

例如,在登陆页面以及注册页面,需要展示相同的广告,则可以通过下面继承的方法实现:

from flask import Flask, views, render_templateapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():return 'Hello World!'class AdsView(views.View):   # 广告内容def __init__(self):super(AdsView, self).__init__()   # 调用父类的init方法self.ad_content = {"product": "GMCC-1001"}def dispatch_request(self):return NotImplementedError     # 因为基类中的这个方法不会被调用class LoginView(AdsView):def dispatch_request(self):return render_template("html/login.html", **self.ad_content)class RegisterView(AdsView):def dispatch_request(self):return render_template("html/registry.html", **self.ad_content)app.add_url_rule(rule="/login/", endpoint="login", view_func=LoginView.as_view("login"))
app.add_url_rule(rule="/registry/", endpoint="registry", view_func=RegisterView.as_view("registry"))if __name__ == '__main__':app.run(debug=True)

通过这种方法,可已将相同的广告内容展示在不同的页面。且修改起来更加的容易。

2. 基于请求方法的视图

Flask还提供了另一种类视图,flask.view.Methodview,对每个http执行不同的函数(映射到对应方法的小写的同名方法上),这对restful API尤其有用。

基于方法的类视图,是根据请求的“method”不同来执行不同的方法的,如果用户是发送的“get”请求,那么将会执行这个类的get方法,如果发送的是post请求,将会执行类的post方法。其他的“method”也类似,例如delete,put方法

from flask import Flask, views, render_template, requestapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():return 'Hello World!'class LoginView(views.MethodView):def get(self, error=None):return render_template("html/login.html", error=error)def post(self):"""获取post请求提交的参数:return:"""username = request.form.get("username")password = request.form.get("password")if username == "knight" and password == "123456":return self.get(error="success")else:return self.get(error="fail")app.add_url_rule(rule="/login/", view_func=LoginView.as_view("login"))if __name__ == '__main__':app.run(debug=True)

前端代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登陆</title>
</head>
<body>
<form action="" method="post"><table><tr><td>用户名</td><td><input type="text" name="username"></td></tr><tr><td>密码</td><td><input type="password" name="password"></td></tr><tr><td></td><td><input type="submit" value="点击登陆"></td></tr></table>{% if error %}{% if error == "success" %}<p style="color: green">登陆成功</p>{% else %}<p style="color: red">登陆失败</p>{% endif %}{% endif %}
</form>
</body>
</html>

类视图中使用装饰器:

1. 如果使用的是函数视图,那么自己定义的装饰器必须放在“app.route()”装饰器的下面才能生效。否则这个装饰器不能起作用。

2. 类视图的装饰器需要重写类视图的一个属性decorates,这个类属性是一个列表或者元组,里面装的就是所有的装饰器。

应用场景:例如网站上的个人信息页面和设置页面,在跳转到这些页面的时候,如果用户没有登陆,则会自动跳转到登陆页面,

提醒用户登陆。只有在登录状态下才能访问这些页面,下面通过装饰器模拟这一功能。

from flask import Flask, views, render_template, request
from functools import wrapsapp = Flask(__name__)app.config["TEMPLATE_AUTO_RELOAD"] = Truedef login_required(func):    # 定义装饰器@wraps(func)    # 保留参数 函数func的一些属性,如__name__属性等def wrapper(*args, **kwargs):username = request.args.get("username")if username and username == "Tom":return func(*args, **kwargs)else:return "请先登陆"return wrapper@app.route('/')
def hello_world():return 'Hello World!'@app.route('/setting/')
@login_required        # 自定义的装饰器应该放在url的下main
def setting():return "User setting"# 给类视图添加装饰器
class ProfileView(views.View):decorators = [login_required]def dispatch_request(self):return "这是个人页面"app.add_url_rule("/profile/", view_func=ProfileView.as_view("profile"))if __name__ == '__main__':app.run(debug=True)

在这些页面中,只有请求参数中有用户名参数的时候,才能够跳转到相应的页面,否则会提示登陆。

蓝图的基本使用:

蓝图用于将一个大型Flask项目分层解耦,进行模块化划分,可以将相同模块的视图函数放在同一个文件中,统一进行管理

例如,网站主要可以划分为新闻,电影,图书,个人中心四个模块,则可以按照如下的方式进行划分:

user.py文件:(初始化蓝图)

# -*- coding: utf-8 -*-
from flask import Blueprintuser_bp = Blueprint("user", __name__, url_prefix="/user")    # 初始化蓝图# 个人中心
@user_bp.route('/profile/')
def profile():return "个人中心页面"@user_bp.route("/settings/")
def settings():return "设置页面"

news.py文件 (初始化蓝图), 同时在news.py中渲染html文件的方法不变:

# -*- coding: utf-8 -*-
from flask import Blueprint, render_templatenews_bp = Blueprint("news", __name__, url_prefix="/news")@news_bp.route("/news_list/")
def news_list():return render_template("html/news_list.html")@news_bp.route("/news_detail/")
def news_detail():return "新闻详情"

在app.py文件中,注册上面创建的蓝图

from flask import Flask, views, render_template, request
from blueprints.user import user_bp
from blueprints.news import news_bpapp = Flask(__name__)
app.register_blueprint(user_bp)
app.register_blueprint(news_bp)app.config["TEMPLATE_AUTO_RELOAD"] = True@app.route('/')
def hello_world():return 'Hello World!'if __name__ == '__main__':app.run(debug=True)

这样就将项目中的视图函数分模块进行管理。

url_prefix:url前缀,如果加了,则视图函数对应的url前面必须有前缀,且只能有一个斜杠

route中还可以指定template_folder参数,如果制定了这个参数template_folder=“xxx”,那么flask在渲染模板的时候,首先会去项目中的templates文件夹中寻找,如果没有找到,flask接下来会去blueprints/xxx文件夹中寻找模板文件。

蓝图中静态文件的寻找规则:

1. 在模板文件中,加载静态文件,如果使用url_for('static'),那么就会在app指定的静态文件夹目录下查找静态文件

2.如果在加载静态文件的时候,指定了蓝图的名字,比如“news.static”,那么Flask就会到这个蓝图指定的static_folder下查找静态文件。

url_for反转蓝图注意事项:

如果需要跨文件反转视图函数,则需要指定视图函数的蓝图名字,再加上视图函数名字,例如:

@app.route('/')
def hello_world():print(url_for("news.news_list"))return 'Hello World!'

例如,需要反转news_list视图函数,则需要在加上其蓝图的名字才可以,在模板中和在python文件中的用法一样,同样需要加蓝图的名字。

即使在同一个蓝图中反转视图函数,也需要指定蓝图的名字。

子域名实现详解:

1. 使用蓝图技术

2. 在创建蓝图对象的时候,需要传递一个"subdomain"参数,来指定这个子域名的前缀:

3. 需要在主app文件中,需要配置serve name参数:

【注】IP地址不能有子域名,localhost不能有子域名

例如,CMS子域名:

# -*- coding: utf-8 -*-
from flask import Blueprintcms_bp = Blueprint("cms", __name__, subdomain="cms")@cms_bp.route("/")
def index():return "Cms index Page"

在app.py文件中设置:

from blueprints.cms import cms_bpapp.register_blueprint(cms_bp)app.config["TEMPLATE_AUTO_RELOAD"] = True
app.config["SERVER NAME"] = "jd.com:5000"
# 修改host文件:
# 127.0.0.1 jd.com
# 127.0.0.1 cms.jd.com

此时设置完毕计算机的host文件后,在本地计算机访问jd.com,就会映射到127.0.0.1

---------------------------------------------------------------------------------------------------------------------------------------

Web后端学习笔记 Flask(4)视图函数相关推荐

  1. Web后端学习笔记 Flask(10)CSRF攻击原理

    CSRF(Cross Site Request Forgery,跨站域请求伪造)是一种网络的攻击方式,它在2007年曾被列为互联网20大安全隐患之一. CSRF攻击的原理: 网站是通过cookie实现 ...

  2. Web后端学习笔记 Flask(9)cookie and session

    Flask_wtf除了可以做表单验证,模板渲染之外,还可以防御CSRF攻击.要了解CSRF攻击的原理,首先需要了解cookie和session的知识点. cookie:在网站中,HTTP请求是无状态的 ...

  3. Web后端学习笔记Flask(2)模板

    模板渲染: 在flask中,视图函数可以直接通过render_template进行模板渲染.在flask中,模板文件是存放在template文件夹中:在调用模板文件的时候,模板文件的路径从templa ...

  4. Web后端学习笔记 Flask(1)基础知识

    基础的准备 1. 使用的python版本 python3.6 2. pycharm编辑器 3. 安装python虚拟环境: python中的虚拟环境: python中的虚拟环境相当于一个抽屉,在这个抽 ...

  5. Web后端学习笔记 Flask(11)Local线程隔离对象

    flask中的上下文:应用上下文和请求上下文 1. 在flask中,是通过request对象获取用户提交的数据,但是在整个程序运行中,只有一个request对象.在实际应用场景中,会有多个用户同时进行 ...

  6. Web后端学习笔记 Flask(8) WTForms 表单验证,文件上传

    Flask-WTF是简化了WTForms操作的一个第三方库.WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板.同时还包含一些其他的功能.例如CSRF保护,文件上传等功能,安装fl ...

  7. Web后端学习笔记 Flask (5) 数据库

    MySql数据库安装:省略 SQLAlchemy介绍和基本使用: 数据库是开发网站的基础,,在Flask中,支持的数据库有:MySql,PostgreSql,SQLite,Redis,MongoDB来 ...

  8. Web后端学习笔记 Flask(7)数据库

    高级查询: 1. group_by 根据某个字段进行分组,比如说需要根据某个字段分组,来统计每组有多少人. 2. having having是对查询结果进一步过滤,比如只想看到未成年人的数量,那么首先 ...

  9. Web后端学习笔记 Flask(6)数据库

    SQLAlchemy一对一关系实现: 在一对多的条件下:给Article表中添加article,只需要将article放入到user的article属性中,再将user添加到user表中即可,此时的a ...

最新文章

  1. ptam tracking
  2. java23中设计模式——结构模式——Composite(组合)
  3. 剑指 Offer 61. 扑克牌中的顺子
  4. 【Java 网络编程】TCP API 简介 ( Socket | ServerSocket )
  5. 7-28 超市贴花 (5 分)
  6. js 和C# ashx之间数组参数传递问题
  7. 支持CDS view的SAP ALV IDA - 使用前提
  8. 尽可能地做到无服务器,但不止于此
  9. 4接口引脚定义_浅谈USB Type-C接口
  10. 研发管理---(1)持续交付
  11. 使用Web API ASP.NET Core 2.2部署Angular 8应用程序
  12. NUnit单元测试笔记
  13. 云服务器架设网站教程_阿里云服务器购买流程详细教程及注意事项
  14. 如何修改WP文章字体格式、字号大小、字体颜色
  15. 分享 | 开源的中文语音识别系统
  16. 如何克服大数据安全问题
  17. htc a620d 刷android,续航以及最后的总结_HTC A620d - CNMO
  18. 【原创】在Windows 环境下利用SVN和Apache以及Ankh配置源代码管理服务
  19. 软件工程师:机器学习也需要学习?
  20. APISpace 语音验证码API

热门文章

  1. 微服务升级_SpringCloud Alibaba工作笔记0018---Nacos之服务注册中心对比提升
  2. C#.Net工作笔记014---C#中internal的意思
  3. System学习笔记002---Windows下输入日文,あ会变成ち
  4. slowfast 跑多卡的时候遇到问题
  5. 2016年1月29日报
  6. NLP之路-实验nltk中的raw 和 words
  7. 杭电2068RPG的错排
  8. C++ 全局变量 静态变量 全局函数 静态函数
  9. 堆内存里的各种奇怪填充值
  10. 基于人人网的简单爬虫(一)——正则表达式