学前准备
安装好Python环境,pycharm。
Flask基础知识
-
python后端有两个主流框架,Flask轻量级框架、Django 重型,继承了很多东西。
Flask是一个基于MVC设计模式的web后端框架
MVC: -
M Model 数据模型
-
V View 界面
-
C Controller 控制层
MTV: -
M: Models 模型(数据)
-
T: Templates 模板(界面)
-
V: View 视图(控制器)
Flask依赖三个库
Jinja2 模板引擎{% %} 模板:静态html+模板语言{% %}
Werkzeug WSGI 工具集
Flask流行的主要原因:
- 有非常齐全的官方文档,上手非常方便
- 有非常好的扩展机制和第三方扩展环境,工作中常见的软件都会有对应的扩展。自己动手实现扩展也很容易。
- 社区活跃度非常高
- 微型框架的形式给了开发者更大的选择空间
安装的时候去搜一下,应该是先创建一个虚拟环境,然后在虚拟环境中pip install Flask。为什么要创建虚拟环境?因为一台服务器上可能部署多个项目,每个项目需要的环境不一样,不能使用统一的一个环境。
//安装虚拟环境(windows操作系统)
pip install virtualenv virtualenvwrapper-win
//查看虚拟环境
workon
//mkvirtualenv 删除虚拟环境
rmvirtualenv flask2env
//进入虚拟环境
workon flask2env
启动文件最好叫app.py。
if __name__ == '__main__':
# 运行启动web服务,持续监听用户端发起的请求
app.run()
//run()启动的时候还可以添加参数:
// debug 是否开启调试模式,开启后修改过python代码会自动重启
// port启动指定服务器的端口号,默认是5000
// host主机,默认是12.0.0.1,指定为0.0.0.0代表本机所有ip
模板渲染
@app.route('/index')
def index():
#模板渲染
return render_template('index.html',name='法外狂徒')
返回JSON数据
@app.route('/index')
def index():
#模板渲染
#return render_template('index.html',name='法外狂徒')
#JSON
#jsonify:序列化
return json.dumps({'name':'张三','age':33},ensure_ascii=False)
路由参数
路由:讲从客户端发送过来的请求分发到指定函数上
路由通过装饰器对应视图函数,并且可以接收参数,所以我们只需要在视图函数上使用装饰器即可
#路由参数
# string 接收任何没有斜杠('/')的文件(默认)
# int 接收整型
# float 接收浮点型
# path 接收路径,可接收斜线('/')
# uuid 只接收uuid字符串,唯一码,一种生成规则
# any 可以同时指定多种路径,进行限定
#string
@app.route('/string/<string:name>')
def get_string(name):
print(name)
return 'string'
#int
@app.route('/int/<int:id>')
def get_int(id):
print(id)
return str(id)
#float
@app.route('/float/<float:money>')
def get_float(money):
print(money)
return str(money)
#path:支持路径/的字符串
@app.route('/path/<path:money>')
def get_path(money):
print(money)
return str(money)
请求方法
默认支持GET,HEAD,OPTIONS,如果想支持某一请求方式,需手动指定
methods中可以指定请求方法:GET、PSOT、HEAD、PUT、DELETE
#methods:请求方式
@app.route('/methods_post',methods=['POST'])
def get_methods():
return 'methods'
请求和响应
Request
服务器在接收到客户端的请求后,会自动创建Request对象
由Flask框架创建,Request对象不可修改
属性
url 完整请求地址
base_url 去掉GET参数的URL
host_url 只有主机和端口号的URL
path 路由中的路径
method 请求方法
remote_addr 请求的客户端地址
args GET请求参数
form POST请求参数
files 文件上传
headers 请求头
cookies 请求中的cookie
ImmutableMultiDict类型:
类似字典的数据结构,与字典的区别,可以存在相同的键
args和form都是ImmutableMultiDict的对象
ImmutableMultiDict中数据获取方式:
dict['uname']或 dict.get('uname')
获取指定key所对应的所有值:
dict.getlist('uname')
#请求响应
# request: 请求
# response: 响应
# http一次前后端交互:先请求,后响应
#Request: 客户端向服务器发送请求
@app.route('/request',methods=['GET','POST'])
def get_request():
pass
print(request) # <Request 'http://127.0.0.1:5001/request'
#重要属性
print(request.method) #请求方式
print(request.args) #GET请求参数
print(request.form) #post请求参数
print(request.form.get('name'))
#cookie
print(request.cookies)
return 'request ok!'
#Response:服务器端向客户端发送的响应
@app.route('/response')
def get_response():
pass
#响应的几种方式
#1.返回字符串(不常用)
#return 'response OK!'
#2.模板渲染(前后端不分离)
#return render_template('index.html',name='张三',age=33)
#3.返回JSON数据(常用,前后端分离)
data = {'name':'李四','age':44}
#返回data
#jsonify()序列化,字典=》字符串
return json.dumps(data)
#4.自定义response对象
res = make_response()
模型Model
Flask模型
#Flask默认并没有提供任何数据库操作的API
#我们可以选择任何适合自己项目的数据库来使用
#Flask中可以自己选择用原生的语句实现功能,也可以选择ORM(SQLAlchemy,MongoEngine)
#原生sql缺点
#代码利用率低,条件复杂代码语句长,有很多相似语句
#一些sql是在业务中拼出来的,修改需要了解业务逻辑
#直接写sql容易忽视sql问题
ORM
/**
Flask通过Model操作数据库,不管你数据库的类型是Mysql或者Sqlite,Flask自动帮你生成相应数据库类型的SQL语句,所以不需要关注SQL语句和类型,对数据的操作Flask帮我们自动完成。只要会写Model就可以了。
Flask使用对象关系映射(Object Relational Mapping,简称ORM)框架去操控数据库。
ORM(Object Relational Mapping)对象关系映射,是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
**/
Flask的ORM
//Flask使用python自带的ORM:SQLAlchemy
//安装支持插件 flask-sqlalchemy (用于ORM)
pip install flask-sqlalchemy
//安装 flask-migrate(用于数据迁移)
pip install flask-migrate
//安装 pymysql(MySQL驱动)
pip install pymysql
数据迁移的步骤:
1、安装好数据迁移包 flask-sqlalchemy和flask-mgrate
2、在exts.py中初始化Migrate和SQLAlchemy
3、在models中定义好模型
4、在views.py中一定要导入models模块
from .models import *
5、配置好数据库(sqlite3或者MySQL)
6、执行数据迁移命令
//执行数据迁移命令
现在cmd或者Terminal进入项目目录(app.py所在目录):
然后输入命令:
flask db init 创建迁移文件夹migrates,只调用一次
flask db migrate 生成迁移文件
flask db upgrade 执行迁移文件中的升级
flask db downgrade 执行迁移文件中的降级
这里插入一下一个官网手册地址:flask-sqlalchemy官方使用手册
下面是一些增删改查操作。
查询数据
过滤器
filter() 把过滤器添加到原查询上,返回一个新的查询
filter_by() 把等值过滤器添加到原查询上,返回一个新查询
limit() 使用指定的值限制原查询返回的结果数量,返回一个新查询
offset() 偏移原查询返回的结果,返回一个新查询
order_by() 根据指定条件对原查询结果进行排序,返回一个新查询
group_by() 根据指定条件对原查询结果进行分组,返回一个新查询
常用查询
all() 以列表形式返回查询的所有结果,返回列表
first() 返回查询的第一个结果,如果没有结果,则返回 None
first_or_404() 返回查询的第一个结果,如果没有结果,则终止请求,返回404错误响应
get() 返回指定主键对应的行,如果没有对应的行,则返回None
get_or_404() 返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回404错误响应
count() 返回查询结果的数量
paginate() 返回一个Paginate对象,它包含指定范围内的结果
查询属性
contains
startswith
endswith
in_
__gt__
__ge__
__lt__
__le__
具体操作的代码
#添加数据
@blue.route('/user/add')
def user_add():
# 添加一条数据
# user = User()
# user.name = 'xiaoming'
# user.age = 23
# user.sex = True
# user.salary = 2500.0
# db.session.add(user) #将user对象添加到session中
# db.session.commit() #同步到数据库中
# 同时添加多条数据
users = []
for i in range(10, 30):
user = User()
user.name = 'xiaotu_' + str(i)
user.age = i
user.salary = 2500 + i
users.append(user)
try:
db.session.add_all(users)
db.session.commit() #事务提交
return 'add Success!'
except Exception as e:
db.session.rollback() #事务回滚
db.session.flush() #清空缓存
return 'fail:' + str(e)
#删除数据
@blue.route('/user/delete')
def user_del():
user = User.query.first() #查询第一条数据
db.session.delete(user)
db.session.commit()
return 'delete success!'
#修改数据
@blue.route('/user/update')
def user_update():
user = User.query.first() #查询第一条数据
user.salary = 15000.0
db.session.commit()
return 'update success!'
#查询数据
@blue.route('/user/query')
def user_query():
"""
all(): 返回所有数据,返回列表
:return:
"""
# users = User.query.all() #查询所有数据
# print(users)
#filter():过滤,类似SQL中的where
# users = User.query.filter() #查询集,可以强制转化为List
# print(users, type(users))
#get() : 查询到对应主键的数据对象
# user = User.query.get(8)
# print(user, type(user))
# print(user.name, user.salary) #获取对象数据的属性
# filter_by() : 用于等值操作的过滤
#users = User.query.filter(User.age>=20) #filter可以用于等值,可以用于非等值操作
#users = User.query.filter_by(age=20) #不能用于非等值操作
#print(list(users))
#first() : 第一条数据
#first_or_404() : 第一条数据,如果不存在就报404错误
# user = User.query.first()
# user = User.query.first_or_404()
# print(user)
# count(): 统计查询集中数据条数
# users = User.query.filter()
# print(users.count())
#limit(): 取前几条数据
#offset():跳过前几条
# users = User.query.offset(3).limit(4) #跳过前三条,取四条数据
# print(list(users))
# order_by() : 排序
# users = User.query.order_by(desc('age')) #默认升序,使用desc降序
# print(list(users))
# 逻辑运输符 and_,or_,not_
#users = User.query.filter(User.age>20, User.age<25) #默认为且
#users = User.query.filter(and_(User.age>20, User.age<25)) #且
#users = User.query.filter(or_(User.age > 25, User.age < 20)) #或
#users = User.query.filter(not_(or_(User.age > 25, User.age < 20))) #非
#print(list(users))
#查询属性
# contains('3'):模糊查找,类似于sql中的like
users = User.query.filter(User.name.contains('3'))
users = User.query.filter(User.age.in_([10, 20, 30, 40, 50]))
#startswith():以X开始 endswith(): 以X结尾
users = User.query.filter(User.name.startswith('冰'))
users = User.query.filter(User.name.endswith('2'))
print(list(users))
return 'query success!'
注意:如果对项目的模型有做更改,比如需要某张表新增一个字段,或者增加一个新的表,需要再次迁移。再次迁移的时候,无需执行init命令,从flask db migrate命令开始执行.
虚拟环境
//查看venv使用
python -m venv -h
//创建虚拟环境
python -m venv venvdemo
//去创建的虚拟环境的Scripts目录下执行activate激活虚拟环境
C:\Users\sunh_\venvdemo\Scripts>activate
anaconda使用
#创建一个虚拟环境
conda create -n 环境名
#查看当前所有的虚拟环境
conda info --envs
conda env list
#激活虚拟环境
Conda activate 环境名
Source activate 环境名
activate + 环境名
#退出环境
deactivate 环境名
#删除环境
conda remove -n 环境名 --all
安装第三方依赖
pip freeze > requirements.txt
pip list --format=freeze > requirements.txt
它会在项目中生成一个requirements.txt文件,文件中记录着导入的第三方依赖,或者直接是pip freeze也可以在控制台直接输出。
//安装依赖
pip install -r requirements.txt
pip install -r requirements.txt -i https://pypi.doubanio.com/simple/
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ffcv -i https://pypi.tuna.tsinghua.edu.cn/simple(清华镜像)