热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Web后端学习笔记Flask(4)视图函数

Flask中的视图函数以及视图类:添加视图函数还可以通过下面的方式add_url_rule进行:app.add_url_rule(rule,endp

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)

前端代码:






用户名
密码
{% if error %}{% if error == "success" %}

登陆成功

{% else %}

登陆失败

{% endif %}{% endif %}



 

类视图中使用装饰器:

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

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


推荐阅读
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • 初学SpringBootch06接口架构风格 RESTful
    ch06-接口架构风格RESTful1.1认识RESTful1.1.1RESTful架构风格1.2RESTful注解1.3RESTful风格的使用1.3.1加入Maven依赖1.3 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • Python15行代码实现免费发送手机短信,推送消息「建议收藏」
    Python15行代码实现免费发 ... [详细]
  • Hello.js 是一个用于连接OAuth2服务的JavascriptRESTFULAPI库,如Go ... [详细]
author-avatar
gfhhhgh_130
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有