name:启动入口

请求钩子:准备工作和收尾工作需要处理,为了让每个视图函数避免编写重复的功能

before_first_request:第一次请求前执行,适合初始化操作,比如创建文件、数据库连接
before_request:每次请求前都执行,适用对请求参数校验、统计工作(访问次数)
after_request:如果没抛出异常(服务器错误请求后每次都执行,适合对数据交互格式做统一设置
teardown_request:每次请求后执行,记录服务器异常信息
服务器异常信息的产生:硬盘、内粗炸了,不是你代码错误

from flask import Flask
app = Flask(__name__)

@app.before_first_request
def before_first_request():
	print("before_first_request")

@app.before_request
def before_request():
	# 假设对请求参数做校验,不符合需求
	# return ‘不符合需求’
	print("before_request")

@app.after_request
def after_request(resp):
	print("after_request")
	resp.headers["Content-Type"] = "application/json"
	return resp

@app.teardown _request
def teardown_request(e):
	print(e)
	print("teardown_request")

@app.route("/")
def aaaa():
	return "aaa"

if __name__ == "__main__":
	app.run(debug=True)

request

request:代表当前请求的request对象
需要导入request
from flask import Flask,request
request的属性:
data:非表单提交数据(ajax)
form:表单的post提交数据
args:get请求?后面拼接的数据
files:获取input标签type为file类型的数据

get方法取字典:
字典.get(键名) :获取键值,获取不到返回None
字典.get("键名","字符串") :获取键值,获取不到返回字符串

request.args是个字典

python就业班第31天----flask视图、内容和模板

from flask import Flask,request
app = Flask(__name__)
@app.route("/")
def hello():
	print(request.method)
	print(request.url)
	print(request.args)
	# print(request.args["password"])
	# 字典通过[]取值,获取不到报错,所以建议使用get
	# 获取不到,返回none,也可以设置默认值
	print(request.args.get("name")) # 获取不到返回none
	print(request.args.get("password","xxoo") # 获取不到返回xxoo

if __name__ == "__main__":
	app.run(debug=True)

python就业班第31天----flask视图、内容和模板

http://127.0.0.1:5000?password=zhangsan&sex=man 记住这个格式

request.form的使用在数据库的案例(第33天)里面


Cookie和Session

http实无状态协议,浏览器请求服务器是无状态的,浏览器、服务器不知道之前这个用户做过什么,每次请求都是一次新的请求

无状态原因:socket套接字进行通信,服务器将请求结果返回给浏览器后,会关闭当前的socket连接

需要保持用户的浏览状态:比如是否登录,浏览过哪些商品
实现方式:

  • 1.客户端存储信息使用cookie
  • 2.在服务端存储使用session

cookie:由浏览器生成,存储在浏览器(键值对方式)。浏览器会将Cookie的key/vaue保存,下次请求同一网站就会发送该Cookie给服务器
cookie:复数形式Cookies
应用:网站广告推送、购物车

需要导入make_response模块和request模块
from flask import Flask,make_response,request

设置方式:

response = make_response("响应体")
response.set_cookie(key,value,max_age)

max_age:过期时间,单位是秒,如果不设置默认是一次浏览器会话结束

获取方式:value = request.cookies.get(“键名”)

例:

from flask import Flask,make_response,request
app = Flask(__name__)

@app.route("/set_cookie/<username>")
def seen_computer(username):
	response = make_response("正在看电脑")
	response.set_cookie("product","lenovo")
	response.set_cookie("username",username,10) # 10秒钟只后,username的cookie消失
	return response

@app.route("/get_cookie")
def get_cookie():
	product = request.cookies.get("product")
	name = request.cookies.get("username")
	return "name is %s,product is %s"%(name,product)

if __name__ == "__main__":
	app.run(debug=True) 

浏览器地址前面找cookies

python就业班第31天----flask视图、内容和模板

session:由服务器设置,存储在服务器,用于
存储敏感信息,比如银行卡、身份证、密码信息、登录信息

需要导入session
from flask import Flask,session

先设置秘钥:
app.config["SECURE_KEY"] = "字符串" 如果不知道键名是什么,可以看Flask的类属性
然后设置session
设置方式:session["key"] = value
获取方式:value = session.get(key)

from flask import Flask,sesison
app = Flask(__name__)
app.config("SECURE_KEY") = 'zxcbhk'
@app.route("/set_session/<username>")
def user_login(username):
	session["username"] = username
	return "%s正在登录" %username

@app.route("/get_session")
def get_session():
	name = session.get("username")
	return "get session,name is %s"%name

if __name__ == "__main__":
	app.run()

本身的内容存储在服务器里面,但是sessionID存在浏览器
sessionID是在cookie里面携带到浏览器里面
由于cookie在浏览器不安全,所有sessionID需要进行加密,加密需要秘钥

停止所有程序:ctrl+F2

不同用户登录,开辟不同的空间,生成不同的sessionID,彼此没关系的

把浏览器的cookie清掉,服务端会让你重新登录

一个浏览器不能登两个淘宝账户,因为一个用户对应一块session空间


上下文:相当于一个容器,保存了Flask程序运行过程中一些信息

共两种:请求上下文和应用上下文
请求上下文:session、request
应用上下文:current_app和g

request:封装每次相关数据,称为请求上下文
session:每个客户端请求的时候,开辟一个空间存储客户的敏感信息

应用上下文:从不同对象获取自己想要的内容,app的代理对象,用来处理用户请求,去处理request(在项目中做全局日志输出)

current_app:用于存储应用程序中的变量。app的代理(local proxy),app的所有都能使用

python就业班第31天----flask视图、内容和模板

g:一次完整请求中有效的(在项目中封装登录器)

有多少个用户访问,创建多少个current_app和g,current_app遍历所有文件,找到用户所要的,给g
g对象:global,全局的,重定向,承着

都需要导入:from flask import Flask,current_app,g

例:

from flask import Flask,current_app,g
app = Flask(__name__)

@app.before_request
def before_request():
	g.name = "zhangsan"   # 请求前设置g

@app.route("/")
def hello_world():
	print(app.config.get("DEBUG"))  # 获取app的DEBUG对象
	print(current_app.config.get("DEBUG"))  # 获取current_app的DEBUG对象
	# 因为current_app是app的代理,所有这两个结果一样
	g.age = 13 # 收到请求后设置g
	print(g.name)
	print(g.age)

	return "hello world"

if __name__ == "__main__":
	app.run(debug=True)

python就业班第31天----flask视图、内容和模板


Flask-Script扩展
flask-script是属于flask中的一个扩展包
python 文件.py runserver -host ip地址

  • 1、可以动态运行程序,指定端口,ip,调试模式等
  • 2、可以配合flask_migrate做数据库迁移

使用步骤:

  • 1.安装flask_script:pip install flask_script
  • 2.导入flask_script的Manager类
  • 3.通过Manager类管理app
  • 4.运行方式:
    python 文件.py runserver -h ip地址 -p 端口 -d (debug模式)

之后就只能在终端中运行,不能在pycharm里右键运行了

要想在pycharm里也能运行,进行下面设置:

python就业班第31天----flask视图、内容和模板
python就业班第31天----flask视图、内容和模板

在Script parameters里面填runserver变量,就可以右键和终端都运行了

例:

from flask import Flask
from flask_script import Manager

app = Flask(__name__)
class MyConfig(object):
	DEBUG = True

# 设置app类的调试模式
app.config.from_object(MyConfig)  # 导入MyConfig中的配置

# 通过Manager类管理app
manager = Manager(app)

@app.route("/")
def hello_world():
	return "hello_world"

if __name__ == "__main__":
	manager.run()


jinja2模板:展示html界面
使用render_temple函数封装模板引擎
需要导入:from flask import Flask,render_template

render_template(“文件.html”,key=value,key2=value2),文件.html需要在templates里面

key和value的意思是把这个值带入到template的html(前面那个参数写的文件)里面

from flask import Flask,render_template
app = Flask(__name__)

@app.route("/")
def hello_world():
	return render_template("file01template.html")

if __name__ == "__main__":
	app.run(debug=True)

template的file01template.html里面写

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Title</title>
	<style>
		.box{
			width:200px;
			height:200px;
			background-color:red;
		}
	</style>
</head>
<body>
	<h2>helloworld</h2>
	<div class="box"></div>
</body>
</html>

python就业班第31天----flask视图、内容和模板

templates里面html高亮提示:右键templates文件夹–>Mark Directory as --> Template Folder,选择jinjia2


jinjia2语法

jinjia2语法:
获取变量的值:{{ }}
{{ number }}
列表第一个:{{ list.0 }} {{ list[0] }}
字典名name:{{ dict.name }} {{ list[name] }}

if分支语句:

{% if 条件 %}

{% elif 条件 %}

{% else 条件 %}

{% endif 条件  %}

for循环:

{% for item in items %}

{% for item in items if item!=5 %}

{% endfor %}

如果直接是mydicct.key,那么这个key是一个字符串,如果是dict[key],那么这么key当成变量

遍历索引(写在for里面):

{{ loop.index0 }}	// 从0开始索引
{{ loop.index }} 	// 从1开始索引

注释:
{# 里面跟的是注释内容 #}

例:

from flask import Flask,render_template
app = Flask(__name__)

@app.route("/")
def hello_world():
	my_number = 0
	my_str = "hello"
	my_tuple = (1,2,3,4,5)
	my_dict = ("name":"zhangsan","age":13)
	return render_template("file02program.html",
	number = my_number,str=my_str,tuple=my_tuple,
	list=my_list,dict=my_dict)

if __name__ == "__main__":
	app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>
	<h2>1.模板取变量</h2>
	<h3>整数:{{ number }}</h3>
	<h3>字符串:{{ tuple }},分开获取:{{ tuple.0 }},{{ tuple[1] }},{{ tuple.2 }}</h3>
	<h3>字典:{{ dict }},分开获取:{{ dict.name }},{{ dict["age"] }}</h3>
	
	<h2>2.遍历数组</h2>
	{% for item in tuple %}
		<li>{{ item }}</li>
	{% endfor %}

	<h2>3.获取列表偶数</h2>
	{% for item in list %}
		{% if item%2 ==0 %}
			<h3>{{ item }}</h3>
		{% endif %}
	{% endfor %}
	
	<h2>4.字典遍历</h2>
	{% for key in dict %}
		<h3>{{ key }}----{{ dict[key] }}</h3>
	{% endfor %}

	<h2>5.遍历列表索引</h2>
	{% for foo in list %}
{#		<h3>索引值:{{ loop.index0 }}</h3>   #}
		<h3>索引值:{{ loop.index }}</h3>
	{% endfor %}
</body>

</html>

过滤器:1.字符串 2.列表
管道: |

例:
将hello变成大写 : <h2>{{ "hello" | upper }}</h2>
字符串过滤器:
safe:禁用转移,让html标签生效
capitalize:首字母变大写,其它变小写
lower:所有都是小写
upper:全部转大写
title:把值中所有单词的首字母都大写
reverse:字符串翻转
format:格式化输出,替换占位符
striptags:渲染之前把所有标签都删掉

<body>
	<h2>字符串过滤器</h2>
	{# safe:禁用转义,让html标签生效 #}
	<p>{{ '<em>hello</em>' | safe }}</p>
	<p>{{ "hello" | capitalize }}</p>
	<p>{{ 'Hello' | lower }}</p>
	<p>{{ 'hello' | upper }}</p>
	<p>{{ "hello python" |  title }}</p>
	<p>{{ "我爱你" | reverse }}</p>
	<p>{{ "%s is %d" | format('age',18) }}</p>
	<p>{{ '<em>hello</em>' | striptags }}</p>
</body>

列表过滤器:
first,last,sum,length,sort

<h2>列表过滤器</h2>
{# first:取第一个元素 #}
<p>{{ [1,2,3,4,5,6] | first }}</p>

{# last:取最后一个元素 #}
<p>{{ [1,2,3,4,5,6] | last }}</p>

{# length:获取列表长度 #}
<p>{{ [1,2,3,4,5,6] | length }}</p>

{# sum:列表求和 #}
<p>{{ [1,2,3] | sum }}</p>

{# sort:列表排序(升序) #}
<p>{{ [6,2,3,1,5,4] | sort }}</p>


如果系统自带满足不了需求,用自定义过滤器:
格式有两种:
1.先定义函数,后将函数添加到过滤器列表中

def 函数名称(list):     # jinjia2传过来的列表,管道前面的
	return "返回值" # 给jinjia2传过去的
...
app.add_template_filter(函数名称,"过滤器名称")

2.定义函数的时候,直接使用过滤器列表装饰
python文件里面写:

@app.template_filter("html里过滤器名称")
def 函数名(list):	// jinjia2传过来的列表,管道前面的
	return "返回值" // 给jinjia2传过去的

html里面写:
{{ [列表] | 过滤器名称 }}

可以同时被两个过滤器过滤,多写个管道就OK
{{ [列表] | 过滤器1 | 过滤器2 }}

from flask import Flask,render_template

app = Flask(__name__)

# 1.先定义函数,后将函数添加到过滤器列表中
def reverseList(list):
	list.reverse()
	return list

#参数1: 表示实现功能的函数,  参数2: 在模板中使用的过滤器名称
app.add_template_filter(reverseList,"reverseArray")

# 2.定义函数的时候,直接使用过滤器列表装饰
@app.template_filter("ouShu")
def getOuShu(list):
	new_list = []
	for item in list:
		if item%2 == 0:
			new_list.append(item)
	return new_list

@app.route("/")
def hello_world():
	return render_template("file04customFilter.html")

if __name__ == "__main__":
	app.run(debug=True)

file04customFilter.html里面写:

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>
	<h2>原数组:{{ [1,2,3,4,5,6] }}</h2>
	<h2>反转数组:{{ [1,2,3,4,5,6] | reverseArray }}</h2>
	<h2>偶数数组:{{ [1,2,3,4,5,6] | ouShu | reverseArray }}</h2>
</body>
</html>

python就业班第31天----flask视图、内容和模板

相关文章:

  • 2022-02-16
  • 2021-07-18
  • 2021-11-20
  • 2021-12-01
  • 2021-12-01
  • 2021-11-07
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-12-25
  • 2021-06-30
  • 2022-02-12
  • 2021-09-29
  • 2021-05-18
相关资源
相似解决方案