创建项目虚拟环境及安装相关依赖
创建项目在项目内打开设置
第一步
第二步
打开项目终端查看虚拟环境是否成功
如果没有成功则需要手动开启
虚拟环境配置好后要安装相关依赖
讲有含有依赖名称的文件放到项目内
然后打开项目终端进行安装
安装好之后可以输入 pip list查看一下是否全部安装
创建flask结构
利用工程模式创建app
在根目录创建create_app.py文件
在里面进行编写
from flask import Flask #导入Flask
from flask_cors import CORS #跨域
def create_app(config):
flask_app=Flask(__name__) #实例化flask对象
#加载配置项
flask_app.config.from_object(config)
#注册蓝图
#绑定db
# 跨域
CORS(flask_app)
return flask_app
项目内创建settings目录里创建config.py文件
在里边编写序偶需要的配置项
class DefaultConfig:
SECRET_KEY='asdasfjsfagfasfa' #cookie秘钥
SQLALCHEMY_DATABASE_URI='' #数据库配置项
SQLALCHEMY_TRACK_MODIFICATIONS=False # 追踪数据的修改信号
SQLALCHEMY_ECHO=True # 是否在控制台打印输出sql语句
JSON_AS_ASCII=False #json类型是否转换
#继承自上边的类,避免以后的修改
class DevConfig(DefaultConfig):
# 数据库类型+数据库操作引擎://用户名:密码@主机名:端口/数据库名
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:mysql密码@127.0.0.1:3306/数据库名'
项目根目录创建app.py文件 在里边导入配置项 app实例create_app
from create_app import create_app #导入创建好的create_app
from settings.config import DevConfig #导入配置项
app=create_app(DevConfig)
#通过功能函数方式创建了对象
可以在里面编写main 运行框架
也可以在调试配置对话框里配置运行
配置好之后下次就可地点击旁边的开始就可以运行
在里面配置蓝图
在项目内创建views目录里创建users.py文件
在里面进行编写
from flask import Blueprint #导入蓝图
from flask_restful import Api,Resource
# # url_prefix # 指定当前蓝图下所有路由的前缀
user_dp=Blueprint('user_dp',__name__,url_prefix='/users') #实例化蓝图对象
api=Api(user_dp) #实例化蓝图收集器#实例化一个Api对象 Api对象的作用是用来搜集路由的
#定义类视图 继承自Resource类,通过Api的实例化对象进行搜集
class UserView(Resource):
def get(self): #测试是否成功
return 'ssss'
#添加路由
api.add_resource(UserView,'/user') #完整地址是 /users/user
然后在create_app.py里注册一下
from flask import Flask #导入Flask
from views.users import user_dp #导入实例化的蓝图对象
from flask_cors import CORS
def create_app(config):
flask_app=Flask(__name__) #实例化flask对象
#加载配置项
flask_app.config.from_object(config)
#注册蓝图
flask_app.register_blueprint(user_dp)
#绑定db
# 跨域
CORS(flask_app)
return flask_app
注册数据库配置
在目录创建models目录里创建model.py文件进行编写模型类
from flask_sqlalchemy import SQLAlchemy #导入
db=SQLAlchemy() #实例化数据库连接对象
#创建模型类
class UserModel2(db.Model):
uid=db.Column(db.Integer,primary_key=True,autoincrement=True,comment='用户ID')
mobile=db.Column(db.String(11),comment='手机号')
username=db.Column(db.String(32),default='',comment='用户名')
img=db.Column(db.String(300),default='',comment='头像')
reg_login=db.Column(db.DateTime,default=datetime.now,comment='注册时间')
intro=db.Column(db.String(256),default='这个人很懒,什么都没有留下',comment='简介')
status=db.Column(db.Boolean,default=False,comment='true:冻结 false:正常')
然后在create_app.py里注册一下
from flask import Flask #导入Flask
from views.users import user_dp #导入实例化的蓝图对象
from models.model import db #导入实例化的数据库连接对象
from flask_cors import CORS
def create_app(config):
flask_app=Flask(__name__) #实例化flask对象
#加载配置项
flask_app.config.from_object(config)
#注册蓝图
flask_app.register_blueprint(user_dp)
#绑定db
db.init_app(flask_app)
# 跨域
CORS(flask_app)
return flask_app
在根目录创建manage.py文件配置迁移项
from flask_script import Manager #Manager类作业是把命令行运行该文件的时候,添加一些命令
from app import app #导入app
from flask_migrate import MigrateCommand,Migrate # 导入迁移类和迁移命令类
from models.model import db #导入实例化后的数据库对象
manage=Manager(app) #实例化命令行管理对象
migrate=Migrate(app,db) #实例化迁移执行类
manage.add_command('db',MigrateCommand) #给命令行管理对象添加一组命令
# 注意编写好了要启动一下
if __name__ == '__main__':
manage.run()
在python终端运行命令进行迁移
# 初始化迁移文件 # 初始化,只需要初始化一次
python manage.py db init
# 生成迁移文件
python manage.py db migrate
# 执行迁移
python manage.py db upgrade
# 迁移完成
注册登录
容联云信息
创建容联云账号,添加测试手机号
然后登录找到主账户id 令牌等
验证码功能实现
在已创建的settings目录下创建sevret.py文件
用来存放容联云信息跟redis数据库信息
class SecretConfig():
RL_ACC_ID='8aaf07088185853e01**********' #ACCOUNT SID(主账户ID)
RL_ACC_TOKEN='8ac934ad5ddf44a4a************' #AUTH TOKEN(账户授权令牌)
RL_APP_ID='8aaf07088185853e0************' #AppID(默认)
RL_TID='1' #短信模板ID
RDS_HOST='127.0.0.1' #redis数据库host
RDS_PORT=6379 #redis端口号
RDS_PASSWORD='密码' #redis密码
在settings目录下的config.py文件中继承一下
from settings.secret import SecretConfig #导入封装的配置项
#继承
class DefaultConfig(SecretConfig):
SECRET_KEY='asdasfjsfagfasfa' #cookie秘钥
SQLALCHEMY_DATABASE_URI='' #数据库配置项
SQLALCHEMY_TRACK_MODIFICATIONS=False # 追踪数据的修改信号
SQLALCHEMY_ECHO=True # 是否在控制台打印输出sql语句
JSON_AS_ASCII=False #json类型是否转换
SMS_TIME=5 #数字5 用来设置有效期时间
#继承自上边的类,避免以后的修改
class DevConfig(DefaultConfig):
# 数据库类型+数据库操作引擎://用户名:密码@主机名:端口/数据库名
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:数据库密码@127.0.0.1:3306/数据库名'
在根目录下创建utils目录里创建SmsTools.py文件
from ronglian_sms_sdk import SmsSDK #导入容联云sdk pip install ronglian_sms_sdk
from settings.secret import SecretConfig #导入封装的配置项
from flask import current_app #获取配置项数据
import json,redis
class SmsTool(SecretConfig):
'''
发送短信
'''
def __init__(self):
accId = current_app.config.get('RL_ACC_ID') #获取封装的ACCOUNT SID(主账户ID)
accToken = current_app.config.get('RL_ACC_TOKEN') #AUTH TOKEN(账户授权令牌)
appId = current_app.config.get('RL_APP_ID') #AppID(默认)
self.sdk = SmsSDK(accId, accToken, appId) #封装一下sdk
host=current_app.config.get('RDS_HOST') #获取存放在secret.py里的host
port=current_app.config.get('RDS_PORT') #获取port
pwd=current_app.config.get('RDS_PASSWORD') #获取redis密码
self.rds=redis.Redis(host=host,port=port,password=pwd) #封装redis
def send(self,phone,code): #接收输入的手机号跟随机验证码
'''
发送短信接口
:param phone: 手机号
:param code: 验证码
:return: Bool 发送成功失败
'''
tid=current_app.config.get('RL_TID')
t=current_app.config.get('SMS_TIME') #取出来的数字是5 有效期 从配置文件获取
#把验证码存到redis里面
key='sms_%s'%phone
self.rds.set(key,code,ex=t*60) #设置有效期5分钟
#发送短信
datas=(code,t) #验证码跟有效期数
rs=self.sdk.sendMessage(tid,phone,datas) #返回的是json字符串
rs_data=json.loads(rs) #转换成json格式
# 如果返回的状态码是000000 正确 注意检验状态码的时候必须是字符串
if rs_data['statusCode']=='000000':
return True
return False
if __name__ == '__main__': #可以在这里先测试一下
from app import app
with app.app_context():
s=SmsTool()
s.send('15936829517','6666')
在蓝图中实现
from flask import Blueprint,jsonify #导入蓝图
from flask_restful import Api,Resource,fields,marshal,reqparse
from models.model import UserModel2,db #把model.py文件中的导入进来
from utils.SmsTools import SmsTool #导入生成验证码的函数
import random #随机功能函数
# # url_prefix # 指定当前蓝图下所有路由的前缀
user_dp=Blueprint('user_dp',__name__,url_prefix='/users') #实例化蓝图对象
api=Api(user_dp) #实例化蓝图收集器#实例化一个Api对象 Api对象的作用是用来搜集路由的
#定义类视图 继承自Resource类,通过Api的实例化对象进行搜集
class SmsView(Resource):
def post(self):
rep=reqparse.RequestParser()
rep.add_argument('phone')
args=rep.parse_args()
code=random.randint(100000,999999)
s=SmsTool() #调用发送验证码的类
rs=s.send(args['phone'],code) #根据输入的手机号发送生成的随机验证码
if rs:
return jsonify({
'code':200,
'msg':'发送成功',
})
return jsonify({
'code':400,
'msg':'发送失败'
})
#添加路由
api.add_resource(SmsView,'/sms') #完整地址是 /users/sms
登录功能实现生成jwt
在创建好的utils目录下创建jwtTools.py文件
import jwt #导入jwt pip install pyjwt
from flask import current_app #获取配置项数据
import time #时间模块
class JwtTools(): #类名
'''
jwt管理
'''
def create(self,payload,ex=3600): #生成jwt
'''
生成jwt
:param payload: 载荷
:return: string jwt
'''
payload['exp']=int(time.time())+ex #默认时间一小时 键名为exp的话 decode函数会自动校验
secret_key=current_app.config.get('SECRET_KEY') #获取session秘钥
token=jwt.encode(payload,secret_key,algorithm='HS256') #生成jwt
print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaa', token) #打印一下是否生成成功
return token # return返回
#校验token
def valid(self,token):
'''
校验jwt
:param token: jwt
:return: Dict payload
'''
secret_key=current_app.config.get('SECRET_KEY') #获取session秘钥
try:
payload=jwt.decode(token,secret_key,algorithms='HS256') #解密token
print(payload)
return payload
except Exception as a:
print(a)
return False
if __name__ == '__main__': #可以在这里测验一下
from app import app
with app.app_context():
j=JwtTools()
jwt_token=j.create({
'aaa':'bbb'
})
a=j.valid(jwt_token)
print(a)
在蓝图中实现登录并携带jwt token功能
from flask import Blueprint,jsonify #导入蓝图
from flask_restful import Api,Resource,fields,marshal,reqparse
from models.model import UserModel2,db
from utils.jwtTools import JwtTools #导入生成jwt的类
from utils.SmsTools import SmsTool #导入生成验证码的类
import random
# # url_prefix # 指定当前蓝图下所有路由的前缀
user_dp=Blueprint('user_dp',__name__,url_prefix='/users') #实例化蓝图对象
api=Api(user_dp) #实例化蓝图收集器#实例化一个Api对象 Api对象的作用是用来搜集路由的
#定义类视图 继承自Resource类,通过Api的实例化对象进行搜集
class SmsView(Resource): #发送验证码
def post(self):
rep=reqparse.RequestParser()
rep.add_argument('phone')
args=rep.parse_args()
code=random.randint(100000,999999)
s=SmsTool() #调用发送验证码的类
rs=s.send(args['phone'],code) #根据输入的手机号发送生成的随机验证码
if rs:
return jsonify({
'code':200,
'msg':'发送成功',
})
return jsonify({
'code':400,
'msg':'发送失败'
})
class UserView(Resource):
def post(self):
#获取参数
req=reqparse.RequestParser()
req.add_argument('phone')
req.add_argument('code')
#校验参数
args=req.parse_args()
#校验验证码是否正确
#先连接redis数据库
s=SmsTool()
#根据手机号拿出对应的验证码
key = 'sms_%s' % args['phone']
code_byte=s.rds.get(key) # 返回值是bute类型
if not code_byte:
return jsonify({
'code':400,
'msg':'验证码已过期'
})
#比对
if args['code']!=code_byte.decode():
return jsonify({
'code':400,
'msg':'验证码错误'
})
#查询以下数据库有没有这个用户
user_info=UserModel2.query.filter(UserModel2.mobile==args['phone']).first()
if not user_info:
#如果没有先注册
#注册:把用户信息插入数据库
u=UserModel2(mobile=args['phone'],username='游客%s'%args['phone'][-4:])
db.session.add(u)
db.session.commit()
#如果有,直接登录
user_data = UserModel2.query.filter(UserModel2.mobile==args['phone']).first()
lists=marshal(user_data,{
'username':fields.String,
})
token=JwtTools().create({
'username':user_data.username,
'uid':user_data.uid
})
print('sssssssssssssssssssssssssssssssss',token)
#返回用户信息返回JWT
return jsonify({
'code':200,
'msg':'登陆成功',
'data':{
'username':user_data.username,
'token':token #token是用来状态保持的
}
})
#JWT三部分
#1.头,固定的
#2.payload 载荷
#3.1+2加密出来的
#添加路由
api.add_resource(SmsView,'/sms') #完整地址是 /users/sms
api.add_resource(UserView,'/user') #完整地址是 /users/user