Flask基础
安装方法 pip install flask
从函数到接口
加法函数
def add(a,b):
return a+b
如果a,b是字符格式的数字呢
args = {'a': '1', 'b':'2'} # 参数字典
def add():
a = args.get('a')
b = args.get('b')
c = int(a) + int(b)
return c
加法接口
# app.py
from flask import Flask,request
app = Flask(__name__)
@app.route('/add')
def add():
a = request.args.get('a') # 参数为字符串格式
b = request.args.get('b') # 参数字符串格式
s = int(a) + int(b)
return str(s) # 响应需为字符串
命令行在脚本所在目录运行flask run
$ flask run
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
如果报错可以配置环境变量LC_ALL=en_US.utf-8
也可以在脚本中添加
if __name__ == '__main__':
app.run()
然后运行该脚本
测试接口 http://127.0.0.1:5000/add?a=1&b=2
使用POST或其他请求方法
@app.route('/add', methods=["GET,POST"])
获取请求数据
- request.args: 请求URL参数字典
- request.form: 请求表单数据字典
- request.json: 请求JSON数据字典
request.values: 请求URL参数和表单数据的组合字典
练习:改为使用表单数据及JSON数据
组装响应
- 返回字符串:
return '3'
- 返回网页:
return '<h1>测试报告</h1>'
- 附带状态码及响应头:
return '',201,{'test': 'abc'}
- 返回JSON数据:
return jsonify({"code": 0, "msg": "success"})
# 需要导入jsonify
渲染并返回网页
from flask import render_template
name=lilei
sex=male
skills=['Python','Java']
...
return render_template('list.html', name=name,sex=sex,skills=skills)
templates/list.html
<h2>{{name}}</h2>
<h2>性别</h2>
{% if sex=male %}
男
{% else %}
女
{% endif %}
<h2>技能</h2>
{% for skill in skills %}
{{skill}}
{% endfor %}
重定向响应
from flask import redirect, url_for
...
return redirect('/') # return redirect(url_for('index'))
终止响应
from flask import abort
...
if not request.args.get('a'):
abort(400)
示例:注册接口
import pymysql
from flask import Flask,request,jsonify,abort
conn = pymysql.connect(host='115.28.108.130', port=3306, user='test', password='abc123456', db='api_test', charset='utf8')
cur = conn.cursor()
@app.route('/api/user/reg/', methods=['POST'])
def reg():
# 参数验证
if not request.json:
abort(400)
name = request.json.get('name')
password = request.json.get('password')
if not name or not password:
abort(400)
# 检查用户名是否存在
result = cur.execute(f'select id form user where name="{name}"')
if result:
return jsonify({'code': '100001', 'msg': '用户已存在'})
# 插入用户数据
try:
cur.execute(f'insert into user (name,passwd) values ("{name}"", "{password}")')
conn.commit()
return jsonify({'code': '100001', 'msg': '注册成功'})
except:
return jsonify({'code': '100002', 'msg': '注册失败'})
练习:编写一个登录接口,支持GET和POST,GET返回登录页面,POST进行登录操作
通过request.method==GET或POST来判断请求方法
登录页面 templates/login.html
<form method="post" action=".">
<div>用户名:<input name="name" type="text"></div>
<div>密码:<input name="password" type="password"></div>
<div><input type="submit">
</form>
app.py
...
@app.route('/api/user/login/', methods=['GET', 'POST'])
def login():
if request.method=='POST':
name = request.form.get('name')
password = request.form.get('password')
if not name or not password:
abort(400)
result = cur.execute(f'select id from user where name="{name}" and passwd="{password}"')
if result:
return '<h1>登录成功</h1>'
else:
return '<h1>用户名或密码错误</h1>'
return render_template('login.html')
password填入
" or "1
发现SQL注入漏洞
使用ORM
ORM对象关系映射,将一个数据库表映射为一个Python的类,使用成熟的ORM框架可以简化数据库操作、减少SQL语句错误及安全问题。
安装flask-sqlalchemy: pip install flask-sqlalchemy
数据库配置
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dev.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
数据模型设计
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
body = db.Column(db.Text)
默认表名为类名转小写,即post,也可以通过 __table__指定表名
使用MySQL数据库 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:密码@115.28.108.130/数据库名' # 需要建表权限
SQLAlchemy常用字段类型
- Ingeger: 整数
- Float: 浮点数
- Boolean: 布尔值
- String: 字符串
- Text: 不限长度的文本
- Date: 日期对象
- Time: 时间对象
- DateTime: 日期时间
- Interval: 时间间隔
常用的SQLAlchemy字段参数
- primary_key: 是否主键
- unique: 是否唯一
- index: 是否索引
- nullable: 可否为空,默认True
- default: 默认值
创建表
进入app.py所在目录,运行
$ flask shell
>>> from app import db
>>> db.create_all()
增删改查
增
>>> from app import db, Post
>>> p = Post(title='第一篇博客', body='第一篇博客正文')
>>> db.session.add(p)
>>> db.session.commit()
查
>>> Post.query.all()
>>> Post.query.get(1)
>>> Post.query.filter_by(title='第一篇博客').first()
- Post.query.all():获取所有数据
- Post.query.one(): 获取一条数据,无数据报错
- Post.query.first(): 获取第一条数据,无数据不报错
- Post.query.get(id): 获取指定id的数据
- Post.query.get_or_404(id): 找不到返回404
- Post.query.filter_by(): 过滤数据,得到一个数据集
删
>>> p = Post.query.get_or_404(1)
>>> db.session.delete(p)
>>> db.commit()
改
>>> p = Post.query.get_or_404(1)
>>> p.title='第一篇博客改'
>>> db.session.commit()