pycharm 查看方法的定义(类似.net 中 F12)
ctrl + 单击(对应的方法)
两种方法
# 先打开cmd 中断 # 查看virtual是否安装过 pip show virtualenv # 安装 pip install virtualenvwrapper-win # workon 查看虚拟环境 vorkon # 切换虚拟环境 # workon 虚拟环境 # mkvirtualenv 创建新的虚拟环境 mkvirtualenv falsk2env # 删除虚拟环境 #rmvirtualenv flask2env #进入虚拟环境 workon flask2env
pip list 查看虚拟环境所有的包
pip freeze 查看自己安装的包
专业版pychram
社区版 要手动创建
from flask import Flask, render_template, jsonify app = Flask(__name__) # 路由可以多个对一个视图函数的 @app.route('/') @app.route('/index/') def index(): # 返回值 # 直接返回 # return 'ZEN' # 模板渲染 # return render_template('index.html',name='123') # 返回json对象 # return {'name':'Ares-Wang','Sex':'男'} # 返回json序列化 return jsonify({'name':'Ares-Wang','Sex':'男'}) @app.route('/') def home(): return 'ARES-ZEN' if __name__ == '__main__': app.run(host='0.0.0.0',debug=True)
--url_for 反向解析
# app.py from APP import Create_App app = Create_App() if __name__ == '__main__': app.run(host='0.0.0.0',debug=True) # views.py # views.py 路径 + 视图函数 from flask import Blueprint from .models import * blue = Blueprint('BlueName', __name__) @blue.route('/') def Home(): return 'SPlIT' # __init__.py # __init__.py :初始化文件、创建Flask应用 from flask import Flask from .views import blue def Create_App(): # 返回Flask对象 app = Flask(__name__) # print(app.config) # SECRET_KEY 是对称加密的密钥,存在浏览器的 # session['xxx']='123',session 通过secret_key 把123 加密存在服务器端 # 同时客户端cookie中存入cookieID 也是加密的 session 设置要配置secret_key # app.config['SECRET_KEY']='ZEN' # 设置session过期时间 # app.config['PERMANENT_SESSION_LIFEATIME']=datetime.timedelta # 注册蓝图 可以注册多个蓝图 app.register_blueprint(blueprint=blue) return app
@app.route(‘/xxx/converter:variable_name’)
converter:参数类型
string:接受任何没有斜杠’/'的字符串 默认参数类型
int:接受整数
float:接受浮点数
path 接受路径, 可接受斜杠(’/‘)的字符串
uuid 只能接受uuid字符串,唯一码,一种生成规则 根GUID一样的
any 可以同时指定多种路径,进行限定
@app.route(‘/student//’) 与 @app.route(‘/student/string:username/’) 一样
@app.route(‘/student/int:id/’)
def get_student(id):
student= Student.query.get(id)
@app.route(‘/student/uuid:id/’)
@app.route(‘/student/float:num/’)
@app.route(‘/student/path:path/’)
@app.route(‘/student//’)
请求方法 常见POST GET
Flask 默认支持GET,不支持POST请求的
@app.route(‘/student/’)
同时支持get 、post 请求
@app.route(‘/student/’,methods=[‘GET’, ‘POST’])
服务器在接受客户端的请求后,会自动创建Request对象,有FLask框架创建,request对象不可修改
# requests 爬虫测试下面的请求对象 import requests request = requests.get('http://127.0.0.1:5000/index/?user=123') request = requests.post('http://127.0.0.1:5000/index/',data={'user':3456}) print(request.text)
from flask import Flask,request @app.route('/index/>',methods=['GET', 'POST']) def get_index(): # 服务器在接受客户端的请求后,会 自动创建 Request 对象,由Flask 框架创建,request 对象不可修改,只能使用 # 获取请求方式 print(request.method) # url 完整请求地址 print(request.url) # http://127.0.0.1:5000/index/?user=123' # base_url 去掉get参数的url print(rquest.base_url) # http://127.0.0.1:5000/index/ # host_url 只有主机名和端口号 print(rquest.host_url) # http://127.0.0.1:5000/ # remote_addr 请求的客户端地址 print(request.remote_addr) #IP地址 # files 文件上传 print(request.files) # 用户代理, 包括浏览器和操作系统的信息 反爬用的 类似 python-requests/2.31.0 print(request.user_agent) # headers 请求头 print(request.headers) # headers 请求中的cookie print(request.cookies) # 获取请求参数 get 请求,返回是字符串 # request.args.get(key,defaultValue) 如果key,没有传参,可以赋默认值, print(request.args.get(key)) # 返回是ImmutableMultiDict类型 print(request.args) # 获取请求参数 post 请求 print(request.from.get(key)) #返回是ImmutableMultiDict类型 print(request.from)
ImmutableMultiDict类型
Respone响应
# 导入模板渲染用的包 from flask import render_template, jsonify, make_response,Response @app.route('/response/') def get_Response(): # 响应的几种方式 # 1、返回字符串(不常用) return 'AresZEN' # 2、模板渲染(前后端不分离) 在templates中创建模板 xx.html 中jinja2语法 {{}} return render_template('xx.html',param1='' , param2='') # 3、返回json数据(前后端分离) return {'name':'Ares','age':30} # jsonify() 序列号 josn=>字符串 return jsonify({'name':'Ares','age':30}) # 4、自定义Response对象 html= render_template('xx.html',param1='' , param2='') # 返回字符串(html格式的字符串) print(html,type(html)) # 导入包make_response(返回的数据,状态码) res=make_response(html,200) # res = Response(html) 跟上面效果一样 res.set_cookie() # 设置cookie # 上面任意一个都可以 return res
@blue.route('redirect') def make_redirect(): # 重定向的几种方式 # return redirect('https://www.baidu.com') # return redirect('/路由/') # 在程序中跳转 # url_for():反向解析,通过视图函数名反过来找路由, 正常是通过路由找视图函数的,反向解析: 就是根据视图函数,找路由 # url_for('蓝图名称.视图函数名') # 注意是蓝图名称 ,不是蓝图对象 blue对象 = Blueprint('BlueName蓝图名称', __name__) # ret = url_for('蓝图名称.视图函数名') # return redirect(rect) # url_for 传参 ret= url_for('蓝图名称.视图函数名',参数名=Value,参数名2=Value2) return redirect(rect2)
设置cookie
获取cookie
request.cookies.get(key)
删除cookie
response.delete_cookie(key)
cookie不能存中文
session服务器端会话技术,依赖于cookie
特点:
- 服务端的会话技术
- 所有数据存储在服务器中
- 默认存储在内存中
- 存储结构:key-value形式,键值对
- session 离不开cookie
- sessionID存储在客户端, session的值存在在服务端
session设置
session[‘key’]=‘value’
获取session 如果不存在,就返回 default指定的值
session.get(key,default=None)
删除session
session.pop(key) 删除某一值
session.clear() 清除所有session
cookie VS session
cookie: ①存储在客户端(浏览器)②安全性较低③可以降低服务器压力
session:①存储在服务端(服务器)②安全性高③对服务器要求较高④仍然需要依赖cookie, 服务器生成的sessionID会返回给客户端,sessionID 存储在客户端。
模板语法主要分为两种:
- 变量
- 标签
模板中的变量 {{ 变量名 }} 变量不存在,默认忽略,不会报错
views 视图函数传递给模板的数据 return render_template(‘xxx.html’,参数1=value1,参数2=Value2)
或者
data ={ ‘age’ :20,‘name’:‘ZEN’ ,hobbys:[‘football’,‘basketball’]}
render_template(‘xxx.html’, **data)
模板中取值 {{ age }} {{name}}
{{ hobbys }} 返回是 [‘football’,‘basketball’] 的字符串 所以一般用for循环取值
循环 for
{% for hobby in hobbys %}
# segment
{% else %} #hobby 不存在了,就进入else 了。
segment
{% endfor %} 要有结束标签
使用 获取循环信息 loop
{% for hobby in hobbys %}
{{hobby}}
index:{{ loop.index }} # 从1开始的下标
index:{{ loop.index0 }} # 从0开始的下标
index:{{ loop.revindex }} # 反向下标,不包括0
index:{{ loop.revindex0 }} # 反向下标,包括0
index:{{ loop.first }} # 判断是否是第一个元素
index:{{ loop.last }} # 判断是否是最后一个元素
模板中的标签 {% tag %} 注意要有结束标签 注意要有结束标签
控制逻辑、使用外部表达式 创建变量 宏定义
{% if age >=18 %}
成年
ParentTemplate
include文件
{% extends 'Base.html'%} {% block extcss %} {% extends '1.html' %} {% block content %} {{super()}}AresZEN
{% endblock %} {# 定义 Python函数} {% macro person(name.age) %} 姓名:{{ name }}, 年龄:{{ age }} {% endmarco %} {% block foot %} {{ person('ZEN',27) }} {% endblock %}
{% extends '1.html' %} {% block content %} {{super()}}AresZEN
{% endblock %}
安装 flask_sqlalchemy (用于ORM)
pip install flask_ sqlalchemy -i https://pypi.douban.com/simple
安装 flask_migrate (用于数据迁移 把数据库模型迁移到数据库中)
pip install flask_ migrate -i https://pypi.douban.com/simple
安装 pymysql (mysql 驱动)
pip install pymysql -i https://pypi.douban.com/simple
Flask中使用ORM
连接数据库需要指定配置
数据库模型的定义
一个数据库模型对应一个数据库中的表,所有的数据库模型都要基础ORM对象的Modle基类,即db.Model
# models.py 模型 数据库 # 创建数据库模型 # 模型 =》 数据库 # 类 =》 表结构 # 类属性 =》 表字段 # 一个对象 =》 表的一个行数据 from .exts import db class Account(db.Model): # 定义数据库的表名 __tablename__ = "account" id = db.Column(db.Integer,primary_key=True, autoincrement=True) account = db.Column(db.String(10),unique=True,nullable=False) username = db.Column(db.String(30),nullable=False) # 定义显示信息 在模型类中,重写 __repr__ 方法, def __repr__(self): """定义之后,可以让显示对象的时候更直观""" return "User object : username =%s" % self.username
# exts.py 插件管理 # 1、导入第三方插件 from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate # 2、 初始化对象 db = SQLAlchemy() # ORM migrate = Migrate() # 数据迁移 # 3、与app对象绑定 def init_exts(app): db.init_app(app=app) migrate.init_app(app=app,db=db)
?# __init__.py :初始化文件、创建Flask应用 import datetime from flask import Flask from .views import blue from .exts import init_exts def Create_App(): # 返回Flask对象 app = Flask(__name__) # ORM 数据库配置 # SQLite 数据库连接不需要额外驱动,也不需要用用户名和密码 SQLite 一般是手机程序用的 本地数据库 DB_URI='sqlite:///sqlite3.db' app.config['SQLALCHEMY_DATABASE_URI']=DB_URI # 配置连接数据库路径DB_URI app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False # 禁用对象追踪修改 # 初始化插件 init_exts(app=app) # 注册蓝图 可以注册多个蓝图 app.register_blueprint(blueprint=blue) return app```
数据迁移 : 就是把model模型在数据库中创建表
配置mysql 前提 要存在这个数据库
DB_URI=’mysql+pymysql://root:root@localhost:3306/数据名‘
表的CRUD操作
要在视图函数操作数据模型,从而同步数据库
# views.py 中 # 蓝图 from flask import Blueprint,render_template,request from .models import * # 蓝图 blue = Blueprint('bluename',__name__) @blue.route('/') def index(): return render_template('index.html') # 表单操作:CRUD操作 @blue.route('/accountadd/',methods=['GET','POST']) def account_add(): # 添加一个记录 Account 是类,定义在models.py u = Account() if request.method=='GET': u.account = request.args.get('account') u.username = request.args.get('username') else: u.account = request.from.get('account') u.username = request.from.get('username') # views.py中没有导入 exts为啥油db对象,因为db对象在models.py 导入了。 因此 views中导入model,相当于也导入了exts db.session.add(u) # 将u对象添加到session中 db.session.commit() # 同步到数据库中 return 'success!' @blue.route('/accountaddall/') def account_add(): # 添加多条记录 Account 是类,定义在models.py users = [] for i in range(1,10): u=Account() u.account = 'ZEN_'+str(i) u.username = 'Ares_'+str(i) users.append(u) # views.py中没有导入 exts为啥油db对象,因为db对象在models.py 导入了。 因此 views中导入model,相当于也导入了exts # db.session.add_all(对象列表) try: db.session.add_all(users) # 将u对象列表添加到session中 db.session.commit() # 同步到数据库中 事务提交 except Exception as e: db.session.rollback() # 回滚 db.session.flush() # 把session中数据清理掉 return 'fail: '+ str(e) return 'success!' @blue.route('/accountdelete/') def account_del(): try: u=Account.query.first() # 查询第一条数据 db.session.delete(u) db.session.commit() except Exception as e: db.session.rollback() db.session.flush() return 'success!' @blue.route('/accountupdate/') def account_update(): try: u=Account.query.first() # 查询第一条数据 u.username='yyds' db.session.commit() except Exception as e: db.session.rollback() db.session.flush() return 'success!' # 查询数据 @blue.route('/userget/') def user_get(): # all(): 以列表形式返回查询的所有结果,返回列表 # users = Account.query.all() # first() 返回查询的第一个结果,如果没有结果,则返回None # user = Account.query.first() 可以继承 过滤器 # filter() 把过滤器添加到原查询上,返回一个新查询,可以继续 . 过滤器 # users = Account.query.filter() 可以继承 过滤器 # user = Account.query.filter(Account.username=='yyds') # filter_by() 把**等值**过滤器添加到原查询上,返回一个新查询 # filter_by() 与 filter() 区别 # user = Account.query.filter_by(username='yyds') # count() 返回查询结果的数量 # users = Account.query.filter() 可以继承 过滤器 print(users.count()) # first_or_404() 返回查询的第一个结果,如果没有结果,则终止请求,返回404错误响应 # user = Account.query.filter_by(username='yyds').first_or_404() # get() 返回指定主键对应的行,如果没有对应的行,则返回None ,此处家人username是主键 # user = Account.query.get(username='yyds') # get_or_404() 返回指定主键对应的行,如果没有找到指定的主键,则终止请求,返回404错误响应 #user = Account.query.get(username='yyds') # limit() 取前面几条 使用指定的值限制原查询返回的结果数量,返回一个新查询 可以继承 过滤器 # offset() 跳过前几条 偏移原查询返回的结果,返回一个新查询 ,可以继承 过滤器 # users = Account.query.offset(3).limit(4) # order_by() 排序 升序 # users = Account.query.order_by('id') # order_by() 排序 降序 需要到包 from sqlalchemy import desc # users = Account.query.order_by(desc('id')) # 逻辑运算符 and_ , or_ , not_ users = Account.query.filter(Account.username='yyds' , Account.id < 100) # 且 默认 # 需要到包 from sqlalchemy import and_ , or_ , not_ users = Account.query.filter(and_(Account.username='yyds', Account.id < 100) # 且 # 查询属性 # contains 模糊查询 类似 sql like users = Account.query.filter(Account.username.contains('yd')) # in_() 其中只有 类似 sql in users = Account.query.filter(Account.username.in_(['yyds','jjz'])) # startswith(): 以某字符串开头 # endswith(): 以某字符串结尾 users = Account.query.filter(Account.username.startswith('yy')) # __gt__ 大于 # __ge__ 大于等于 # __lt__ 小于 # __le__ 小于等于 users = Account.query.filter(Account.id.__gt__(300)) return 'success!'
Title
@blue.route('/paginate/') def get_info(): page = int(request.args.get('page', 1)) per_page = int(request.args.get('per_page', 5)) Accounts = Account.query.paginate( page=page, per_page=per_page ).items return render_template('info.html', Accounts)
多表关联
## model.py 一对多 案例 # models.py 模型 :和数据库相关的 from .exts import db """ department :employee =》 1:N 1对多 外键要设置在 N: 多的 一个表 """ # 创建 department 部门表 即 Department 模型 # 模型需要继承db.Model,否则就普通的类 class Department(db.Model): # 表名 __tablename__ = 'department' id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 部门编号 deptCode = db.Column(db.String(30), nullable=False) # 建立关联 # 第一个参数:关联的模型名,因python语言是解释性语言,Employees, 需要需要 用 '' # 第二个参数:反向引用的名称,department 对象 # 让employee去反过来得到department对象的名称 employee.department 是个department对象 # 第三个参数: 延迟加载,懒加载, 用到的时候,才会建立关系,懒加载:为了提高性能,节约资源 # 这里departments不是字段,不是字段 是类的属性 employees = db.relationship('Employees', backref='department', lazy=True) """ 查询员工所属的部门,反向引用department emp = Employee.query.get('emp_Code值') # department 要跟 backref对应的值保持一致 # emp.department 返回是department对象 dept = emp.department code=dept.deptCode 查询某部门下面的所有员工 dept = Department.query.get('deptCode值') dept.employees # 所有部门编码下的员工信息 返回是employee 对象列表 """ # 创建employee 员工表 即 Employee 模型 # 模型需要继承db.Model,否则就普通的类 class Employee(db.Model): # 表名 __tablename__ = 'employee' id = db.Column(db.Integer, autoincrement=True) # 员工姓名 emp_name = db.Column(db.String(30), nullable=False) # 员工编号 emp_Code = db.Column(db.String(30),nullable=False, unique=True, primary_key=True) # 外键 也是字段, 跟 员工表的 员工编号关联 1:N 外键也放在N的表中 # 实现一对多关系,要在对应的表 添加 db.relationship department = db.Column(db.String(30),db.ForeignKey(Department.deptCode), nullable=False, unique=True)
N:M 多对多关系,还存在两个表的中间表:关联作用
# models.py from .ext import db # usermodel 和 usermodel 建立关联表 collect = db.Table( # 表名 'collects', # 组合主键 # 字段 db.Column('user_id',db.Integer,db.ForeignKey('usermodel.id'),primary_key=True) db.Column('sysmodel_id',db.Integer,db.ForeignKey('sysmodel.id'),primary_key=True) ) # 用户表 Class UserModel(db.Model): __tablename__='usermodel' # 字段 id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db,String(30)) userCode = db.Column(db.String(30),) # 系统模块 Class SysModel(db.Model): __tablename__:'sysmodel' id = db.Column(db.Integer,primary_key=True,autoincrement=True) name = db.Column(db.String(30)) # 关联 # secondary=collect: 设置中间表 users =db.relationship('UserModel',backref='sysmodels',lazy=True,secondary=collect)
# views.py """ 用户表和系统模块表 追加数据略 """ @blue.route('/addcollect/') def add_collect(): # 用户拥有的系统模块 user = UserModel.query.get('key') sysmodel = SysModel.query.get('key') # user.sysmodels 是反向查询的 backref='sysmodels' user.sysmodels.append(sysmodel) db.session.commit() return 'success!' @blue.route('/getcollect/') def get_collect(): # 查询某用户拥有的系统模块 user = UserModel.query.get('key') print(user.sysmodels) # 返回list # 查询系统模块拥有的用户 sysmodel = SysModel.query.get('key') print(sysmodel.users) # 返回是查询集 可以继续用filter 、filter_by过滤方法 print(list(sysmodel.usrs)) 返回list @blue.route('/deluser/') def del_user(): # 多对对 关联删除是级联删除,跟1对多删除不一样, 1对多, 1的一方删除数据,多的一方 对应数据外键 null user = UserModel.query.get('key') db.session.delete(user) db.session.commit() # 删除用户,对应用户在中间表collect中记录也会删除。
安装:
pip install flask-caching # 是连接符,不是下划线
# exts.py 插件管理 # 1、导入第三方插件 from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate # 是下划线,不是连接符 from flask_caching import Cache # 2、 初始化对象 db = SQLAlchemy() # ORM migrate = Migrate() # 数据迁移 cache = Cache(config = { 'CACHE_TYPE':'simple' }) # 3、与app对象绑定 def init_exts(app): db.init_app(app=app) migrate.init_app(app=app,db=db) cache.init_app(app=app)
cache 应用
# views.py # @ 装饰器 @blue.route('/') @cache.cached(timeout=20) @ 开始访问(执行里面的代码),第二个方法缓存(不执行代码),缓存有效期20s,超时,会再次访问执行里面的代码 def home(): print('xxx') # 模拟访问复杂的逻辑运算 time.sleep(5) return 'ZEN'
钩子函数(中间件 MIddleware)是执行函数(视图函数)和目标函数之前挂载的函数,框架开发者给调用方提供一个point-挂载点
是一个AOP切面编程思想
常用钩子函数
用爬虫访问 如果没有做反爬 (headers没配置 cookie、user-agent)
request.user_agent.string # python-requests/2.28.2 类似这种结果
from .exts import * # views.py #钩子函数不需要配置路由 @blue.before_request def before(): ip=request.remote_addr # cache.get() cache.set() if cache.get(ip): # 做了拦截,不会进入视图函数 return '禁止爬虫访问!' else: # 对每个IP配置一个缓存,1秒内不让重复访问 cache.set(ip,'value',timeout=1) # string 别忘记 if "python" in request.user_agent.string: return "禁止用python爬虫" # @ 装饰器 @blue.route('/') @cache.cached(timeout=20) @ 开始访问(执行里面的代码),第二个方法缓存(不执行代码),缓存有效期20s,超时,会再次访问执行里面的代码 def home(): print('xxx') # 模拟访问复杂的逻辑运算 time.sleep(5) return 'ZEN'
# views.py 钩子函数 @blue.before_request def before(): # Flask内置对象 # request : 请求对象 # session : 会话对象 # g : global 全局对象 # current_app Flask应用对象 g.xx = 'yyds'
默认 static、templates 跟__init__.py 是平级的, app=Flask(name)
如果不是平级 要在初始化app=Flask(name,static_folder=‘路径’,template_folder=‘路径’)
render_template 模板渲染 是前端和后端混在一起的
.net 中基于MVC框架的 webapi 是专门做接口的,后端的, python值flask框架提供了flask-restful包
render_template 用在views.py中的,是 # 视图函数: FBV Function Based View 路由用@装饰器
类视图 : CBV Class Based View 不需要是使用后端分离的, 不需要有views.py 不用路由@装饰器
flask-restful
安装
pip install flask-restful
# exts.py 插件管理 # 1、导入第三方插件 from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate # 是下划线,不是连接符 from flask_caching import Cache # 注意是Api from flask_restfull import Api # 2、 初始化对象 db = SQLAlchemy() # ORM migrate = Migrate() # 数据迁移 cache = Cache(config = { 'CACHE_TYPE':'simple' }) api = Api() # 3、与app对象绑定 def init_exts(app): db.init_app(app=app) migrate.init_app(app=app,db=db) cache.init_app(app=app) api.init_app(app=app)
app.py
运行前先加载__init__.py
init.py中会加载三个包
from flask import Flask
– 插件管理—
from .exts import init_exts
– 路由—
from .urls import *
在执行app.py 的Create_App(),创建flask对象, 同时给这个flask对象绑定插件
# app.py # Create_APP 写在__init__.py 中,所以导入把 要 包名 APP from APP import Create_App app = Create_App() if __name__ == '__main__': app.run(host='0.0.0.0',debug=True)
# __init__.py :初始化文件、创建Flask应用 from flask import Flask from .exts import init_exts from .urls import * def Create_App(): # 返回Flask对象 app = Flask(__name__) # 初始化插件,创建的app应用,附加了哪些插件 init_exts(app=app) return app
# exts.py 插件管理 三部曲 # 1、导入第三方插件 from flask_restful import Api # 2、 初始化对象 api=Api() # 3、与app对象绑定 def init_exts(app): api.init_app(app=app)
# apis.py 接口用的 from flask_restful import Resource # 类视图 : CBV Class Based View # 视图函数: FBV Function Based View # 继承Resource class StudentResource(Resource): def get(self): return '我是get 请求' def post(self): return '我是Post请求'
# urls.py 路由文件 from .exts import api from .apis import * # 注册路由 api.add_resource(类视图 ,路由) api.add_resource(StudentResource,'/stu/')
为了定义规范接口输出数据格式,要对字段格式化
分两步:
1、fields进行定义
2、在接口用@装饰器修饰 @marshal_with(需要返回的数据格式)
说明:
如果返回的数据在预定义的结构中存在,数据会正常返回
如果返回的数据比预定义结构中字段少,预定义的字段会呈现默认值。默认值也可以设定
如果返回的数据不在预定义结构中,则数据会被自动过滤(舍弃)
# apis.py from flask_restful import Resource,fields,marshal_with # 输出字段格式 ret_info={ 'name':fields.String, 'age':fields.Integer, 'SchoolName':fields.String, 'address':fields.String } # 输出字段格式 ret_fields={ 'status':fields.Integer, 'isSecces':fields.String(default='fail'), # 对方用data,其实映射是password数据的值 'data':fields.String(attribute='password'), 'msg':fields.String, 'studentinfo':fields.Nested(ret_info) } # 继承Resource class StudentResource(Resource): @marshal_with(ret_fields) def get(self): # Student是models.py 需要数据迁移 stu=Student.query.first() return { 'status':200, 'isSecces':'ok', 'msg':'win', 'password':'123', # Student信息 'studentinfo':stu } ret_fields2={ 'status':fields.Integer, 'isSecces':fields.String(default='fail'), # 对方用data,其实映射是password数据的值 'data':fields.String(attribute='password'), 'msg':fields.String, 'studentinfo':fields.List(fields.Nested(ret_info)) } class StudentALLResource(Resource): @marshal_with(ret_fields2) def get(self): # Student是models.py 需要数据迁移 stu=Student.query.all() return { 'status':200, 'isSecces':'ok', 'msg':'win', 'password':'123', # Student信息 'studentinfo':stu } """ # 返回的结果 { "status": 200, "isSecces": "ok", "data": "123", "msg": "win", "studentinfo":[ { "name":"ZEN", "age":33, "SchoolName":"家里蹲", "address":"中国" }, { "name":"ZEN1", "age":331, "SchoolName":"家里蹲1", "address":"中国1" } ] } """ ret_url={ 'name':fields.String, 'url':fields.url(endpoint='id',absolute=False) } class urlResource(Resource): @marshal_with(ret_url) def get(self): return { 'name':200, 'url':'/' } """ # 返回的结果 { "status": 200, "isSecces": "ok", "data": "123", "msg": "win", "studentinfo":{ "name":"ZEN", "age":33, "SchoolName":"家里蹲", "address":"中国" } } """
# urls.py 路由文件 from .exts import api from .apis import * # 路由 api.add_resource(StudentResource,'/') api.add_resource(urlResource,'/url/',endpoint='id') api.add_resource(StudentALLResource,'/stuall/')
可以不通过post : request.form 或 get : request.args 获取参数。而是通过reqparse.RequestParser 来解析
# apis.py from flask_restful import Resource,reqparse # 参数转换器 parser = reqparse.RequestParser() parser.add_argument('name',type=str) parser.add_argument('info',type=str,action='append') # 支持多个info parser.add_argument('cookiex',type=str,location='cookies') # 获取cookies中数据 class StudentResource(Resource): def get(self): # 获取参数 args=parser.parse_args() name=args.get('name') return { 'key':name }
# spider.py 爬虫测试 import requests request = requests.get('http://127.0.0.1:5000/', json={ 'name':'23', 'info':['123','erew'] }, headers={ 'Content-Type':'application/json' } ) print(request.text)