Flask框架基础
1,下载Flask
建议后面的所有操作都在一个虚拟环境中运行哦。
在上一篇的web框架基础中说过Flask的介绍,Flask主要依赖库有两个,Werkzeug和Jinja2。Werkzeug是一个WSGI(在web中和多个服务器之间的标准python接口)工具集,Jinja2负责渲染。安装Flask会自动安装这两个以来啦,包括Falsk一些其他的扩展也会重复安装依赖。 pip install flask
一般直接安装没有任何问题。不行就换国内源,关掉代理。比如我在安装的时候就开着代理,导致安装不了,关掉代理,使用的清华源,没有任何问题,包括后面安装其他扩展也是一样哦
2,Falsk基础
1,第一个应用
python
# _*_ coding: utf-8 _*_
# @Time : 2023/9/22 20:28
# @Author : jiaojiao
from flask import Flask #导入类
app = Flask(__name__) #创建实例,这里使用的是一个模块,里面的名称就是"__name__"
@app.route('/') #这是个装饰器,url,用来触发下面的函数
def index(): #这是个视图函数
return 'Hello World!'
if __name__ == '__main__':
app.run()
2,为了不用每次点击运行,咱们开启一个调试模式
在上面的代码中加入
ini
app.debug=Ture
app.run()
#或者
app.run(debug=Tur)
3,路由
客户端发送请求给web服务器后,服务器把请求给Flask程序实例。程序实例要知道每个请求应该运行哪些代码,所以的保存url和函数之间的关系就叫路由。在Falsk程序里边们最简单的就是装饰器啦``app.route
,把装饰器注册为路由。
装饰器的常见用法是将函数注册为事件的处理程序。
1,设置动态的url
由于url有的时候是动态变化的。比如用户名。我们要对url添加变量,并且进行限制,一般是<变量类型:变量名>
python
# _*_ coding: utf-8 _*_
# @Time : 2023/9/22 20:28
# @Author : jiaojiao
from flask import Flask,url_for,redirect
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
@app.route('/user/<username>')
def show_user_profile(username):
# 显示该用户名的用户信息
return f'用户名是:{username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# 根据ID显示文章,ID是整型数据
return f'ID是:{post_id}'
if __name__ == '__main__':
app.run(debug = True)
上面的post------id是一个整数转换
int:接受整数
float:接受浮点数
path:接受斜线或者其他。
2,构造url
为啥要构造url呢,在后面会有一个生成url的地方,它可以直接跳转页面。 url_for()用来构造URL,结合redirect(),用来跳转到构造的url页面,这两个函数要从Falsk导入
js
#返回hello_world函数对应的路由"/"
url_for('hello_world')
#返回show_post函数对应得路由"/post/2"
url_for('show_post',post_id=2)
简单写个代码,访问127.0.0.1:5000/login
python
# _*_ coding: utf-8 _*_
# @Time : 2023/9/22 20:28
# @Author : jiaojiao
from flask import Flask,url_for,redirect
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
@app.route('/user/<username>')
def show_user_profile(username):
# 显示该用户名的用户信息
return f'用户名是:{username}'
@app.route('/post/<int:post_id>')
def show_post(post_id):
# 根据ID显示文章,ID是整型数据
return f'ID是:{post_id}'
@app.route('/login')
def login():
# 模拟登录流程
flag = 'success'
# 如果登录成功,跳转到首页
if flag:
return redirect(url_for('index'))
return "登录页面"
if __name__ == '__main__':
app.run(debug = True)
自己感受吧。
3,http方法
路由默认情况下,之回应浏览器得get请求,可以通过装饰器得mmethods参数改变这个行为哦。
HTTP Request Method共计15种
序号 | 方法 | 描述 |
---|---|---|
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 实体中包含一个表,表中说明与该URI所表示的原内容的区别。 |
10 | MOVE | 请求服务器将指定的页面移至另一个网络地址。 |
11 | COPY | 请求服务器将指定的页面拷贝至另一个网络地址。 |
12 | LINK | 请求服务器建立链接关系。 |
13 | UNLINK | 断开链接关系。 |
14 | WRAPPED | 允许客户端发送经过封装的请求。 |
15 | Extension-mothed | 在不改动协议的前提下,可增加另外的方法。 |
常用得就两个,get和post
4,模板
模板就是一个响应文本文件,不过里面得内容大部分是变量。得通过渲染才可以知道具体得内容。为啥要这么做呢。后面再说。
1,渲染模板
创建一个templates文件夹存放模板。Flask使用render_template()函数渲染模板 render_template('tempalte_name.html',template_variable=name)
第一个是渲染模板名称,其余参数为模板得变量值
比如红圈里的就需要渲染。render_template('index.html',name=name)
2,模板变量
{{name}}
这个结构就是一个变量,一种特殊的占位符,它可以告诉模板引擎从这个位置的值从渲染模板时使用的数据拿取。Jinja2可以识别所有的类型的变量,字典啊,列表啊吗,对象啊。 在Jinja2中,过滤器是一种特殊函数。juejin.cn/post/711320... Jinja2中还提供了一些控制结构,来改变渲染流程。这个后面的项目中再说吧。
5,Web表单
这下要开始咱们的扩展了,Falsk不会处理表单,需要使用Flask-WTF扩展,它让表单的定义和处理变的轻轻松松。 pip install flask-wtf
1,CSRF保护和验证
CSRF是跨站请求伪造。它可以通过第三方伪造表单数据,post到服务器上面。一般都得做一个保护。咱们的的Flask-WTF它得依赖包WTForms在渲染每一个表单时都会生成一个独一无二得token,这个token在post请求中随着表单数据一块传递,在表单被接收之前进行验证。token得值取决于存储在用户会话cookies中得一个值,这个值一般在30分钟后失效。也就是是只有登陆了页面得用户才可以提交有效得表单。
为了实现CSRF保护,Falsk-WTF需要程序设置一个密钥,通过密钥生成密钥令牌,在用令牌来验证请求表单得数据真假。
js
app=Falsk(__name__)
app.config('SECRET_KEY')='mrsoft'
这里的app.config可以用来存储框架,扩展和程序本身得配置变量。
2,表单类
就是继承一下Form类,类中定义得表单字段用对象表示。字段对象可以附属一个或者多个验证函数。 来个示例代码
python
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField,SubmitField
from wtforms.validators import DataRequired,Length
class LoginForm(FlaskForm):
"""
登录表单类
"""
name = StringField(label='用户名', validators=[
DataRequired("用户名不能为空"),
Length(max=10,min=3,message="用户名长度必须大于3且小于8")
])
password = PasswordField(label='密码', validators=[
DataRequired("密码不能为空"),
Length(max=10, min=6, message="用户名长度必须大于6且小于10")
])
submit = SubmitField(label="提交")
WTForms支持的HTML标准字段
字段类型 | 说明 |
---|---|
StringField | 文本字段 |
TextAreaField | 多行文本字段 |
PasswordField | 密码文本字段 |
HiddenField | 隐藏文本字段 |
DateField | 文本字段,值为datetime.date格式 |
DateTimeField | 文本字段,值为datetime.datetime格式 |
IntegerField | 文本字段,值为整数 |
DecimalField | 文本字段,值为decimal.Decimal |
FloatField | 文本字段,值为浮点数 |
BooleanField | 复选框,值为True和False |
RadioField | 一组单选框 |
SelectField | 下拉列表 |
SelectMultipleField | 下拉列表,可选择多个值 |
FileField | 文件上传字段 |
SubmitField | 表单提交按钮 |
FormField | 把表单作为字段嵌入另一个表单 |
FieldList | 一组指定类型的字段 |
WTForms验证函数
验证函数 | 说明 |
---|---|
验证电子邮件地址 | |
EqualTo | 比较两个字段的值,常用于要求输入两次密码进行确认的情况 |
IPAddress | 验证IPv4网络地址 |
Length | 验证输入字符串的长度 |
NumberRange | 验证输入的值在数字范围内 |
Optional | 无输入值时跳过其他验证函数 |
DataRequired | 确保字段中有数据 |
Regexp | 使用正则表达式验证输入值 |
URL | 验证URL |
AnyOf | 确保输入值在可选值列表中 |
NoneOf | 确保输入值不在可选列表中 |
3,将表单类渲染为HTML
1,创建表单类
python
# _*_ coding: utf-8 _*_
# @Time : 2023/9/22 20:28
# @Author : jiaojiao
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField,SubmitField
from wtforms.validators import DataRequired,Length
class LoginForm(FlaskForm):
"""
登录表单类
"""
name = StringField(label='用户名', validators=[
DataRequired("用户名不能为空"),
Length(max=10,min=3,message="用户名长度必须大于3且小于8")
])
password = PasswordField(label='密码', validators=[
DataRequired("密码不能为空"),
Length(max=10, min=6, message="用户名长度必须大于6且小于10")
])
submit = SubmitField(label="提交")
2,创建视图函数
python
# _*_ coding: utf-8 _*_
# @Time : 2023/9/22 20:28
# @Author : jiaojiao
from flask import Flask ,url_for,redirect, render_template
from models import LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mrsoft'
@app.route('/login', methods=['GET', 'POST'])
def login():
"""
登录页面
"""
form = LoginForm()
if form.validate_on_submit():
username = form.name.data
password = form.password.data
if username== "andy" and password == "mrsoft":
return redirect(url_for('index'))
return render_template('upload.html',form=form)
@app.route('/')
def index():
"""
首页
"""
name = "jiaojiao"
message = """
农大蕉蕉
"""
return render_template("index.html",name=name,message=message)
if __name__ == '__main__':
app.run(debug=True)
3,渲染login.html页面
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/css/bootstrap.css">
<script src="/static/js/jquery.js"></script>
<script src="/static/js/bootstrap.js"></script>
</head>
<body>
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">1</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">2</a>
</li>
<!-- Dropdown -->
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#"
id="navbardrop" data-toggle="dropdown">
3
</a>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">4</a>
<a class="dropdown-item" href="#">5</a>
<a class="dropdown-item" href="#">6</a>
</div>
</li>
</ul>
</nav>
<div class="jumbotron">
<form action="" method="post">
<div class="form-group">
{{ form.name.label }}
{{ form.name(class="form-control")}}
{% for err in form.name.errors %}
<p style="color: red">{{ err }}</p>
{% endfor %}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
{% for err in form.password.errors %}
<p style="color: red">{{ err }}</p>
{% endfor %}
</div>
{{ form.csrf_token }}
{{ form.submit(class="btn btn-primary") }}
</form>
</div>
</body>
</html>
运行视图函数的文件试试吧。
6,蓝图
蓝图是一个存储操作方法的容器,它被注册到一个应用上后,可以调用这些操作方法。蓝图需要注册到一个应用对象上才可以生效。
1,为什么使用蓝图
1,一个应用分为多个蓝图的集合,一个项目可以实例化一个应用对象,。初始化几个扩展,并注册多个蓝图。
2,以URL前缀/子域名,在应用上可以注册一个蓝图。URL前缀/子域名中的参数即成为这个蓝图下所有视图函数的共同视图参数
3,在一个应用中,用不同的URL规则可以多次注册一个蓝图。
4,通过蓝图可提供模板过滤器、静态文件、模板,以及其他功能,
5,初始化一个Flask扩展时,需要注册一个蓝图。
蓝图的基本设想是:但它们被注册到应用上时,会记录将被执行的操作;当分派请求和生成从一个端点到另一个URL时,Flask会关联到蓝图中的视图函数。 这两天看到一个网课,讲的还不错,就是关于蓝图的。www.bilibili.com/video/BV1yE...
7,Flask常用扩展
Flask框架时一个微型框架,它只保留了最核心的功能,通过扩展来增加其他功能。
1,Flask-SQLAIchemy扩展
SQLAIchemy框架是一个常用的数据库抽象层和数据库关系映射包(ORM) 安装的话直接 pip install Flask-SQLAIchemy
基本使用的话juejin.cn/post/723134...
2,Falsk-Migrate
这个帮助更新数据表结构的 因为在更新表结构后,使用create_all方法不会起到更新表的作用,需要先进行数据库迁移,然后更新表结构。juejin.cn/post/703208... 其实也可以使用SQL语句进行更新,可能方便一点。
3,Flask-Script
这个扩展为Flask应用添加了一个命令行解析器,自定义python shell,通过脚本来设置数据库,周期性任务和其他功能。juejin.cn/post/684490...