一、路由规则
路由的请求和响应流程:
1、路由: @app.route(‘/’) def test(): PASS
2、路由的变量规则: String (缺省值) 接受任何不包含斜杠的文本 int 接受正整数 * float 接受正浮点数 path 类似 String,但可以包含斜杠 uuid 接受 UUID 字符串 uuid = uuid.uuid4()
example:
@app.route('/getcity/<key>')
def get_city(key):
print(type(key))
return data.get(key)
@app.route('/add/<int:num>')
def add(num):
result = num + 18
return str(result)
@app.route('/add/<int:num1>/<int:num2>')
def add2(num1,num2):
if num1>0 and num2>0:
result = num1 + num2
return str(result)
return '输入的两个数必须大于0'
@app.route('/add1/<float:money>')
def add1(money):
return str(money)
@app.route('/index/<path:p>')
def get_path(p):
return p
@app.route('/test/<uuid:uid>')
def get_uid(uid):
return ui
结果:
3、返回值: 类型:html、字符串,dict,tuple,response,WSGI
@app.route('/index1')
def index1():
return '<h1>北京</h1>'
@app.route('/index2')
def index2():
return ('beijing','shanghai','shenzhen')
@app.route('/index3')
def index3():
return Response('<h1>大家想好中午吃什么了吗?</h1>')
@app.route('/index4')
def index4():
print(request.headers)
print(request.path)
print(request.base_url)
print(request.url)
return 'welcome everyone!'
@app.route('/register2',methods=['GET','POST'])
def register2():
username = request.form.get('username')
password = request.form.get('password')
repassword = request.form.get('repassword')
if password == repassword and username != '':
user = {'username':username,'password':password}
users.append(user)
return redirect(url_for('index'))
return render_template('register2.html')
结果:
endpoint 与 url_for的结合使用: 1、用 url_for() 来给指定的函数构造 URL,第一个 参数为函数名,其它未知变量作为查询参数
@app.route('/',endpoint='index')
def hello_word():
return render_template('index.html')
@app.route('/test')
def test():
url = url_for('index')
url2 = url_for('hello_word')
url3 = url_for('hello_word',next='/')
print(url)
print(url2)
print(url3)
print(url)
二、对象
request对象
request方法/属性 | 作用 |
---|
request.path | 获取当前请求路由 | request.full_path | 获取当前请求的完整路径 | request.form.get(‘’) | 获取post请求数据 | request.args.get(‘’) —>get请求 | 获取get请求数据 | request.headers | 获取请求头部信息 | request.base_url | 获取请求的 |
response对象
response方法/属性 | 作用 |
---|
response(‘字符串’,headers={key:value}) | | response = make_response(‘…’) | 设置响应体 | response.headers[‘aaa’] = ‘abc’ | 修改响应结果头部字段aaa的值 | response.content_type | 获取响应结果的内容类型 | response.headers | 获取响应结果的头部信息 | response.status_code | 获取响应结果的状态码 | response.status | 获取响应结果的状态信息 |
视图函数的返回值: response响应: 1、str 自动转化为response对象 2、dict json 3、response对象 response对象 4、make_response() response对象 5、redirect(location,statuscode,response) 重定向
location参数是重定向响应的URL statuscode发送到浏览器标头,默认为302 response参数用于实例化响应
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
? 6、Flask.abort(code) 带有错误代码的函数
400 - 用于错误请求
401 - 用于未身份验证的
403 - Forbidden
404 - 未找到
406 - 表示不接受
415 - 用于不支持的媒体类型
429 - 请求过多
? 7、render_template 模板渲染
8、get_flashed_messages()
cookies对象
Cookie以文本文件的形式存储在客户端的计算机上。其目的是记住和跟踪与客户使用相关的数据,以获得更好的访问者体验和网站统计信息
cookie方法/属性 | 作用 |
---|
resp = make_response(“success”) # 设置响应体 resp.set_cookie(“key”, “value”, max_age=3600) | 设置cookie | request.cookies.get(“key”) | 获取cookie中key对应的值 | resp = make_response(“del success”) # 设置响应体 resp.delete_cookie(“key”) | 删除cookie,只是让cookie过期,并不是直接删除cookie |
Session会话
Session(会话)数据存储在服务器上。会话是客户端登录到服务器并注销服务器的时间间隔。需要在该会话中保存的数据会存储在服务器上的临时目录中,会话数据存储在cookie的顶部,服务器以加密方式对其进行签名
Session方法/属性 | 作用 |
---|
Session[key] = value | 设置一个会话变量 | session.pop(key, None) | 释放会话变量key | app.secret_key = ‘value’ | 设置秘钥 |
g全局变量
三、模板
模板: (网页,即template下的html文件)
- 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
- 使用真实值替换变量,再返回最终得到的字符串,这个过程称为’渲染’
- Flask 是使用 Jinja2 这个模板引擎来渲染模板
使用模板的优点:
- 视图函数只负责业务逻辑和数据处理(业务逻辑方面)
- 而模板则取到视图函数的数据结果进行展示(视图展示方面)
- 代码结构清晰,耦合度低
模板的语法: 1、在模板中获取view中传递的变量值:{{ 变量名key }}
render_template(‘模板文件名’,keyvalue,keyvalue,…)
@app.route('/register')
def register():
r = render_template('register2.html')
print(r)
return r
2、模板中接收值 接收列表值: {{ list.0 }} 或 {{ list[0] }} 接收字典值: {{ dict.key }} 或 {{ dict.get(key) }} 接收对象值: {{ girl.name }} 应用外部文件名: url_for(‘static’,filename = ‘css/style.css’) 申明变量进行使用1: {% set username = ‘zhangsan’ %} {{ username }} 申明变量进行使用2: {% with num=1— %} {{ num }} {% endwith %}
example:
app1.py
from flask import Flask,request,render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
class Girl:
def __init__(self,name,addr):
self.name = name
self.gender = '女'
self.addr = addr
@app.route('/show')
def show():
name = 'haha'
age = 18
friends = ['haha', 'hehe', 'xixi', 'qiaqia']
dicts = {'gift1':'项链','gift2':'鲜花','gift3':'戒指'}
girlfriend = Girl('翠花','江西')
return render_template('show.html',name=name,age=age,friends=friends,dicts=dicts,girl=girlfriend)
if __name__ == '__main__':
app.run()
show.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>用户信息展示</div>
<p>
用户名是:{{name}} ---- {{age}} --- {{gender}}
<br>
{{friends[0]}}
{{friends.1}}
{{friends[2]}}
{{friends[3]}}
<br>
{{dicts.gift1}}
{{dicts.get('gift2'}}
<br>
{{girl.name}} --- {{girl.gender}} --- {{girl.age}}
</p>
<table>
{#动态创建#}
<tr>
<td></td>
</tr>
</table>
<script>
</script>
</body>
</html>
结果:
3、控制块
… {% if 条件 %} 条件为True后执行的语句 {% else %} 条件为False后执行的语句 {% endif %} … {% for 变量 in 可迭代对象 %} for要执行的语句 {% endfor %} … 可以使用loop变量 loop.index 序号从1开始 loop.index0 序号从0开始 loop.revindex 序号倒转 loop.revindex0 loop.first 是否第一个 布尔类型 loop.last 是否最后一个 布尔类型
example:
app2.py
from flask import Flask,request,render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
@app.route('/show')
def show1():
girls = ['孙艺珍','松韵','赵丽颖','杨紫','胡冰卿','孙雯']
users = [
{'username': 'haha1', 'password': '123', 'addr': '浙江', 'phone': '10000000000'},
{'username': 'haha2', 'password': '124', 'addr': '浙江', 'phone': '10000000001'},
{'username': 'haha3', 'password': '125', 'addr': '上海', 'phone': '10000000002'},
{'username': 'haha4', 'password': '126', 'addr': '北京', 'phone': '10000000003'},
{'username': 'haha5', 'password': '127', 'addr': '江苏', 'phone': '10000000004'},
{'username': 'haha6', 'password': '128', 'addr': '江西', 'phone': '10000000005'},
]
return render_template('show_controlblock.html',girls=girls,users=users)
if __name__ == '__main__':
app.run()
show_controlblock.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>演示控制块</title>
<style>
.a {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
{# ul...li #}
{# ol...li #}
{# {{girls}} #}
<ul>
{% for girl in girls %}
<li> {{ girl }} </li>
{% endfor %}
</ul>
<hr>
<ul>
{% for girl in girls %}
{% if girl|length >= 3 %}
<li class="a"> {{ girl }} </li>
{% else %}
<li> {{ girl }} </li>
{% endif %}
{% endfor %}
</ul>
<hr>
<table border="1" cellpadding="0" cellspacing="0" width="50%">
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.addr }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
<hr>
<table border="1" cellpadding="0" cellspacing="0" width="50%">
{% for user in users %}
<tr {% if loop.last %} style="background-color: deeppink" {% endif %}>
<td>{{ loop.index0 }}</td>
<td>{{ loop.index }}</td>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.addr }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
结果:
4、过滤器 过滤器的本质就是函数 模板语法中过滤器: {{ 变量名 | 过滤器 }}
{{ 变量名 | 过滤器(*args) }}
常见的过滤器: 1、safe : 转义 保留样式,不使标签进行转义,让其依然可展示样式 2、capitalize : 单词首字母大写 3、lower/upper:单词大小写转换 4、title : 一句话中的每个单词的首字母大写 5、reverse : 单词字母倒拼 6、format : 格式转换 7、truncate : 返回一个截断的长度字串 8、列表中存在的过滤器: {{ girls | first }} {{ girls | last }} {{ girl | length }} {{ [1,3,5,7,9] | sum }} {{ [2,0,1,5.8,3] | sort }} 9、tojson() : 将给定的对象转换为JSON表示
<script type=text/javascript>
doSomethingWith({{ user.username|tojson|safe }});
</script>
10、字典中存在的过滤器: 获取值:
{% for v in users.0.values() %}
<p>{{ v }} </p>
{% endfor %}
获取键:
{% for v in users.0.keys() %}
<p>{{ v }} </p>
{% endfor %}
获取键值对:
{% for k,v in users.0.items() %}
<p>{{ k }}---{{ v }}</p>
{% endfor %}
11、自定义过滤器 1、通过flask模块中的add_template_filter方法
def replace_hello(value):
print('---->',value)
value = value.replace('hello','')
print('=======>',value)
return value.strip()
app.add_template_filter(replace_hello,'replace')
2、使用装饰器完成
@app.template_filter('listreverse')
def reverse_list(li):
temp_li = list(li)
temp_li.reverse()
return temp_li
3、手动添加到应用jinja_env
def reverse_filter(s):
return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter
example:
app3.py
from flask import Flask,request,render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
@app.route('/show')
def show1():
girls = ['孙艺珍','松韵','赵丽颖','杨紫','胡冰卿','孙雯']
users = [
{'username': 'haha1', 'password': '123', 'addr': '浙江', 'phone': '10000000000'},
{'username': 'haha2', 'password': '124', 'addr': '浙江', 'phone': '10000000001'},
{'username': 'haha3', 'password': '125', 'addr': '上海', 'phone': '10000000002'},
{'username': 'haha4', 'password': '126', 'addr': '北京', 'phone': '10000000003'},
{'username': 'haha5', 'password': '127', 'addr': '江苏', 'phone': '10000000004'},
{'username': 'haha6', 'password': '128', 'addr': '江西', 'phone': '10000000005'},
]
girls.append('zhangsan')
msg = '<h1>520快乐!</h1>'
n1 = 'hello'
return render_template('show_controlblock.html',girls=girls,users=users,msg=msg,n1=n1)
@app.route('/')
def hello_word():
msg = 'hello everyone hello world'
li = [3,4,5]
return render_template('define_filter.html',msg=msg,li=li)
def replace_hello(value):
print('---->',value)
value = value.replace('hello','')
print('=======>',value)
return value.strip()
app.add_template_filter(replace_hello,'replace')
@app.template_filter('listreverse')
def reverse_list(li):
temp_li = list(li)
temp_li.reverse()
return temp_li
if __name__ == '__main__':
app.run()
show_controlblock.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>演示控制块</title>
<style>
.a {
color: red;
font-weight: bold;
}
</style>
</head>
<body>
{# ul...li #}
{# ol...li #}
{# {{girls}} #}
<ul>
{% for girl in girls %}
<li> {{ girl }} </li>
{% endfor %}
</ul>
<hr>
<ul>
{% for girl in girls %}
{% if girl|length >= 3 %}
<li class="a"> {{ girl }} </li>
{% else %}
<li> {{ girl }} </li>
{% endif %}
{% endfor %}
</ul>
<hr>
<table border="1" cellpadding="0" cellspacing="0" width="50%">
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.addr }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
<hr>
<table border="1" cellpadding="0" cellspacing="0" width="50%">
{% for user in users %}
<tr {% if loop.last %} style="background-color: deeppink" {% endif %}>
<td>{{ loop.index0 }}</td>
<td>{{ loop.index }}</td>
<td>{{ user.username }}</td>
<td>{{ user.password }}</td>
<td>{{ user.addr }}</td>
<td>{{ user.phone }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
define_filter.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器的使用</title>
</head>
<body>
当前用户共:{{ girls | length }} 人
<br>
{# 过滤器转义 #}
{{ len(girls) }}
<br>
{{ msg | safe }}
<br>
{{ n1 | capitalize }}
<br>
{{ n1 | upper }}
<br>
{{ n2 | lower }}
<br>
{{ n1 | reverse }}
<br>
{{ '%s id %d' | format('lili',18 }}
<br>
{{ 'hello world' | truncate(7) }}
{# 列表过滤器的使用 #}
{{ girls | first }}
<br>
{{ girls | last }}
<br>
{{ girl | length }}
<br>
{{ [1,3,5,7,9] | sum }}
<br>
{{ [2,0,1,5.8,3] | sort }}
<br>
<p>
{{ users.0 }}
<br>
{% for v in users.0.values() %}
<p>{{ v }} </p>
{% endfor %}
<hr>
{% for k,v in users.0.items() %}
<p>{{ k }}---{{ v }}</p>
{% endfor %}
</p>
</body>
</html>
结果:
11、复用 模板继承: 需要模板继承的情况: 1、多个模板具有完全相同的顶部和底部 2、多个模板具有相同的模板内容,但是内容中部分不一样 3、多个模板具有完全相同的模板 标签: {% block name %} {% endblock %} 步骤:1、先在父模板中使用标签留出变化区(注意:样式和脚本需要提前预留) {% block name %} {% endblock %} 2、子模板继承父模板 {% extends ‘父模板名称’ %} 3、再在子模板中通过父模板中响应名称的变量名,进行填充 {% block name %} 变化内容 {% endblock %}
- include:包含
使用场景:在A,B,C页面都有共同的部分,但是其他页面没有这部分 步骤: 1、先定义一个公共的模板部分:.html 2、*使用include导入进需要使用的文件(注意:文件夹必须是在template里面) {% include '文件夹/.html’ %} - 宏:macro
1、把它看作是jinja2的一个函数,这个函数可以返回一个HTML字符串 2、目的:代码可以复用,避免代码冗余 定义的两种方式: 1、在模板中直接定义: 类似:macro1.html 中定义方式 2、将所有宏提取到一个模板中:macro.html 使用时进行导入: {% import ‘macro.html’ as 调用名 %} {{ 调用名.宏(参数值) }} - {{ url_for(‘static’,filename=‘’) }}:加载static下面的静态文件
使用场景:加载例如javaScript或css等文件
example:
app4.py
from flask import Flask,request,render_template
import settings
app = Flask(__name__)
app.config.from_object(settings)
@app.route('/base')
def load_inherit():
return render_template('inherit.html')
@app.route('/')
def index():
return render_template('inherit2.html')
@app.route('/welcome')
def welcome():
return render_template('include.html')
@app.route('/macro')
def use_macro():
return render_template('macro/macro1.html')
@app.route('/macro1')
def use_macro1():
return render_template("macro/macro2.html")
@app.route('/index')
def welcome():
return render_template('index.html')
if __name__ == '__main__':
app.run()
inherit.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}父模板的title{% endblock %}
</title>
<style>
#head{
height : 50px;
background-color : bisque;
}
#head ul{
list-style: none;
}
#head ul li{
float : left;
width : 100px;
text-align : center;
font-size : 50px;
line-height: 50px;
}
#middle{
height : 900px;
background-color : azure;
}
#foot{
height : 50px;
line-height : 50px;
background-color : darkseagreen;
}
</style>
{% block mycss %}
{% endblock %}
</head>
<body>
<div id="head">
<ul>
<li>首页</li>
<li>秒杀</li>
<li>超市</li>
<li>图书</li>
<li>会员</li>
</ul>
</div>
<div id="middle" >
{% block middle %}
<button>我是中间部分</button>
{% endblock %}
</div>
<div id="foot">
我是底部部分
</div>
{% block myjs %}
{% endblock %}
</body>
</html>
inherit2.html
{% extends 'base.html' %}
{% block title %}
首页
{% endblock %}
{% block mycss %}
<style>
#middle{
background-color : deeppink;
}
.div1{
width: 33%;
height: 500px;
float: left;
border: 1px solid red;
}
</style>
<# link rel="stylesheet" href="../static/css/style.css" #>
<link rel="stylesheet" href="{{ url_for('static',filename = 'css/style.css') }}">
{% endblock %}
{% block myjs %}
<script>
btn = document.getElementById('btn')
btn.onclick(function(){
alert('别点我啊!')
})
</script>
{% endblock %}
{% block middle %}
<div class="div1" id="d1"></div>
<div class="div1"></div>
<div class="div1"></div>
<img src="{{ url_for('static',filename='images/a.png')}}" alt="" >
{% endblock %}
header.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>头部</title>
</head>
<body>
<div style="heigh: 50px;background-color: deeppink"></div>
</body>
</html>
include.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>欢迎页面</title>
</head>
<body>
{% include 'common/header.html' %}
<div style="background-color: darkseagreen; width: 100px; "></div>
</body>
</html>
macro/macro1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏</title>
</head>
<body>
{# 定义宏 #}
{% macro form(action,value='登录',method='post') %}
<form action="{{ action }}" method="{{ method }}">
<input type="text" value="" placeholder="用户名" name="username">
<br>
<input type="password" placeholder="密码" name="password">
<br>
<input type="submit" value="{{ value }}">
</form>
{% endmacro %}
{# 调用宏 #}
{{ form('/') }}
</body>
</html>
macro/macro.html
{# 定义宏 #}
{% macro form(action,value='登录',method='post') %}
<form action="{{ action }}" method="{{ method }}">
<input type="text" value="" placeholder="用户名" name="username">
<br>
<input type="password" placeholder="密码" name="password">
<br>
<input type="submit" value="{{ value }}">
</form>
{% endmacro %}
macro/macro2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>宏的使用2</title>
</head>
<body>
{% import 'macro/macro.html' as f %}
{{ f.form('welcome',value='注册') }}
{# 申明变量进行使用 #}}
{% set username = 'zhangsan' %}
{{ username }}
{% with num=1--- %}
{{ num }}
{% endwith %}
</body>
</html>
hello.js
function sayHello() {
alert("Hello World")
}
index.html
<html>
<head>
<script type = "text/javascript"
src = "{{ url_for('static', filename = 'hello.js') }}" ></script>
</head>
<body>
<input type = "button" onclick = "sayHello()" value = "Say Hello" />
</body>
</html>
总结: 变量:{{ name }} 块: {% if 条件 %} …{% endif %} {% for 条件 %} …{% endfor %} {% block 条件 %} …{% endblock %} {% macro 条件 %} …{% endmacro %}
{% include ‘’ %} 包含 {% import ‘’ %} 导入 {% extends ‘’ %} 继承
{{ url_for(‘static’,filename=‘’) }} {{ 宏name(***) }}
|