环境的搭建
检查Python环境
方法一:终端命令行下输入 Python 方法二:终端命令行输入 python -V 注意:Python版本最好是当前最新版本(最低不能低于3.7)
python
python -V
创建虚拟环境
- 创建项目文件
- 进入项目文件
- 创建虚拟环境
$ mkdir myproject
$ cd myproject
$ python3 -m venv venv
注意: 创建完虚拟环境后项目文件下回多出venv文件夹
激活虚拟环境
在终端命令行窗口中执行
. venv/bin/activate
source venv/bin/activate
安装Flask
pip install Flask
pip freeze 检查安装版本号
一个简单的实例
- 创建Python文件
- 导入Flask类
- 创建一个该Flask类的实例
- 用装饰器route告诉Flask触发URL
- 运行flask
注意:这里Python文件名如果是app.py或者wsgi.py可以不用设置FLASK_APP环境变量
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello</p>"
$ export FLASK_APP=hello
$ flask run
路由
作用使用有意义的URL方便用户记忆
from flask import Flask
app=Flask(__name__)
@app.route('/index')
def index():
return '<h1>index</h1>'
@app.route('/home')
def home():
return '<h1>home</h1>'
路由变量规则
- 服务端接受刻画段传递参数
客户端通过URL向服务器传递参数时通过<value_name>这种形式传递.其中value_name是要传递的变量名
from flask import Flask
app=Flask(__name__)
@app.route('/index/<name>')
def index(name):
return '<h1>index,接受的值为{}</h1>'.format(name)
2. 服务端要求客户端传递某一种数据类型参数 客户端通过URL向服务器传递某一种类型参数<value_type:value_name>其中value_type是变量数据类型value_name变量名称
from flask import Flask
app=Flask(__name__)
@app.route('/index/<int:name>')
def index(name):
return '<h1>index,接受的值为{}</h1>'.format(name)
开启调试模式(debug)
调试模式默认是禁用的
- 命令行启动debug
(venv) $ export FLASK_APP=hello.py
(venv) $ export FLASK_DEBUG=1
(venv) $ flask run
- app.run()方式启动debug
app.run(debug=True)
from flask import Flask
app=Flask(__name__)
@app.route('/index/<int:name>')
def index(name):
return '<h1>index,接受的值为{}</h1>'.format(name)
@app.route('/home/<cname>')
def home(cname):
return '<h1>home{}</h1>'.format(cname)
if __name__=="__main__":
app.run(debug=True)
请求-响应循环
- 导入上下文包
- 激活上下文
- 请求上下文
from manage import app
from flask import current_app
app_ctx=app.context()
app_ctx.push()
current_app.name
app_ctx.pop()
请求分派
flask通过app.route装饰器或者app.add_url_rule()方法构建URL 通过app.url_map查询flask创建路由情况,客户端对应请求方式, 视图函数
flask 常用的请求对象
属性方法 | 说明 |
---|
form | 一个字典,存储请求提交的所有表单字段 | args | “一个字典,存储通过 URL 查询字符串传递的所有参数” | values | “一个字典,form 和 args 的合集 | cookies | “一个字典,存储请求的所有 cookie” | headers | “一个字典,存储请求的所有 HTTP 首部” | files | 一个字典,存储请求上传的所有文件 | get_data() | 返回请求主体缓冲的数据 | get_json() | 返回一个 Python 字典,包含解析请求主体后得到的 JSON | blueprint | 处理请求的 Flask 蓝本的名称 | endpoint | 处理请求的 Flask 端点的名称 | method | HTTP 请求方法,例如 GET 或 POST | scheme | URL 方案(http 或 https ) | is_secure() | 通过安全的连接(HTTPS)发送请求时返回 True |
请求钩子
在请求开始之前或者之后代码会很有用,例如:我们要创建数据库链接或者发起用户的身份认证 注册函数 作用是为了比避免在每视图函数中重复调用 注册函数根据请求分配到视图函数 4种请求钩子(注册函数)
- before_request—>>注册一个函数在每次请求之前
- before_first_request —>> 注册一个函数,在第一次请求之前
- after_request —>> 注册一个函数在,没有报错前提下,每次请求执行完毕后执行
- teardown_request —>> 注册一个函数,即使在报错情况下,请求完毕后也 执行
响应
在客户端发出请求后Flask调用视图函数后,返回内容叫做响应 响应状态码 返回响应需要使用不同的状态码用来表示请求是否有效
返回响应对象
通过make_response()返回一个响应对象
from flask import Flask,make_response
app=Flask(__name__)
@app.route('/home')
def home():
response=make_response('<h1>this document Carries a cookie</h1>')
return response
响应对象常见属性方法
属性方法 | 说明 |
---|
tatus_code | HTTP 数字状态码 | headers | 一个类似字典的对象,包含随响应发送的所有首部 | set_cookie() | 为响应添加一个 cookie | delete_cookie() | 删除一个 cookie | content_length | 响应主体的长度 | content_type | 响应主体的媒体类型 | set_data() | 使用字符串或字节值设定响应 | get_data() | 获取响应主体 |
##响应重定向 作用 告诉浏览器一个新的URL,加载新的页面 状态码 302
from flask import Flask,redirect
app=Flask(__name__)
@app.route('/')
def main():
return redirect('http://www.baidu.com')
abort()响应用于处理错误
使用情况 如果需要做用户id认证判断是否为真实用户 abort判断不是真实用户会从服务器端直接终止响应
from flask import abort
@app.route('/usr/<id>')
def usr(id):
if str(id)!="hello":
abort(401)
return "<p>输入id为{}</p>".format(id)
模板
给Flask实例传递一个关键字参数template_folder,指定具体的路径用来改变模板路径
from flask import Flask
app=Flask(__name__,template_folder='./templates')
基本使用
- 在templates文件中创建要渲染的html文件
- 导入render_template 包
- 在视图函数中返回render_template(‘path’)path返回给客户端html文件路径
from flask import Flask,render_template
app=Flask(__name__,template_folder='./templates')
@app.route('/')
def home():
return render_template('main.html')
if __name__=='__main__':
app.run(debug=True)
视图函数—>>html文件传递参数
- 通过变量的形式html_name=def_value
html_name html中要渲染的参数 def_value 视图函数中变量名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{name}}</h1>
</body>
</html>
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
id='hello'
return render_template('main.html',name=id)
if __name__=='__main__':
app.run(debug=True)
- 通过字典的形式
render_template(‘path’,**context) **context 其中context 是传递的字典变量名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{name}}</h1>
<h1>{{age}}</h1>
<h1>{{sex}}</h1>
</body>
</html>
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
context={
'name':'zhangsan',
'age':18,
'sex':'男'
}
return render_template('main.html',**context)
if __name__=='__main__':
app.run(debug=True)
模板过滤器
语法:{{name|filt_name}} name变量名 filt_name 过滤器名称
过滤器名称 | 说明 |
---|
safe | 渲染值时不转义 | capitalize | 把值的首字母转换成大写,其他字母转换成小写 | lower | 把值转换成小写形式 | upper | 把值转换成大写形式 | title | 把值中每个单词的首字母都转换成大写 | trim | 把值的首尾空格删掉 | striptags | 渲染之前把值中所有的 HTML 标签都删掉 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>{{name|length}}</h1>
<h1>{{age}}</h1>
<h1>{{sex}}</h1>
</body>
</html>
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
context={
'name':'zhangsan',
'age':18,
'sex':'男'
}
return render_template('main.html',**context)
if __name__=='__main__':
app.run(debug=True)
在这里插入代码片
if判断语句
模板 {%if 判断语句%} 代码块 {%elif判断语句%} 代码块 {%else%} 代码块 {%endif%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% if age > 10 %}
<h1>大于10</h1>
{%elif age <10%}
<h1>小于10</h1>
{%else%}
<h1>既不小于10也不大于10</h1>
{%endif%}
<h1></h1>
</body>
</html>
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
context={
'name':'zhangsan',
'age':18,
}
return render_template('main.html',**context)
if __name__=='__main__':
app.run(debug=True)
循环语句
列表循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{%for i in PhoneNumber %}
<ul>
<li>电话号码:{{i}}</li>
</ul>
{%endfor%}
</body>
</html>
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
context={
'name':'zhangsan',
'age':18,
'sex':'男',
'PhoneNumber':[188888888888,13312341234,18999999999]
}
return render_template('main.html',**context)
if __name__=='__main__':
app.run(debug=True)
字典循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{%for key,value in msg.items() %}
<ul>
<li>{{key}}---->>>>{{value}}</li>
</ul>
{%endfor%}
</body>
</html>
from multiprocessing import context
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def home():
context={
'name':'zhangsan',
'age':18,
'sex':'男',
'PhoneNumber':[188888888888,13312341234,18999999999],
'msg':{'学号':'0927','班级':'三年级二班',}
}
return render_template('main.html',**context)
if __name__=='__main__':
app.run(debug=True)
宏定义
模板继承
- 定义父模板(基础模板)
- 在基础模板中使用block和endbock指令定义内容区块
- 子模板(衍生模板)中使用extends继承基础模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> {% block title %}{% endblock %} </title>
</head>
<body>
<ul>
<li>
<a href="/">首页</a>
</li>
<li>
<a href="/blog">博客</a>
</li>
<li>
<a href="/msg">信息</a>
</li>
</ul>
{% block body %}{% endblock %}
<footer style="background-color: rgba(29, 29, 59, 0.333);">我是底部</footer>
</body>
</html>
{% extends 'father.html' %}
{% block title %}
个人信息
{% endblock %}
{% block body %}
<h1>我的个人信息</h1>
{% endblock %}
模板引用
- 在基础模板写好HTMl代码
- 在衍生模板中使用{%include‘基础模板名称’%}
<a href="/">首页</a>
<a href="/blog">博客</a>
<a href="/msg">个人信息</a>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> {% block title %}{% endblock %} </title>
</head>
<body>
{% include 'navigation.html' %}
{% block body %}{% endblock %}
<footer style="background-color: rgba(29, 29, 59, 0.333);">我是底部</footer>
</body>
</html>
Web 表单
虚拟环境下安装依赖
(venv) $ pip install flask-wtf
配置防盗秘钥
SECRTE_KEY可以是任意字符串
app = Flask(__name__)
app.config['SECRET_KEY']='这是一个防止CSRF秘钥'
定义表单类
- 创建表单类
- 表单渲染HTML—>>客户端
- 客户端提交表单---->>服务器
- 处理客户端提交表单---->>返回给客户端
from flask_wtf import FlaskForm
from wtforms import StringField,SubmitField
from wtforms.validators import DataRequired
class NameForm(FlaskForm):
iname=StringField('What is you name?',validators=[DataRequired()])
submit=SubmitField('提交')
二实例化列表传给客户端
@app.route('/',methods=['GET','POST'])
def index():
form=NameForm()
name=None
if form.validate_on_submit():
name=form.iname.data
form.iname.data=''
return render_template('index.html',form=form,name=name)
|