Flask+SQLAlchemy+alembic+Flask-RESTful使用
前言
其实准备把这篇删掉,先写Flask-restful相关的,后来想想大体框架还是先写出来,这两天踩了很多坑,有的谷歌也没有答案.一直摸索也总算是开始了.
正文
SQLAlchemy/alembic 的 使用方法之前写过,详见我的博客,今天讲讲如何与 flask-restful 结合一起(只是简单的讲讲搭配,Flask-restful以后会详细讲述)
搭建大体框架
其实与普通的 Flask 差不多,只不过app的功能模块中我们需要加一个 models 文件存放我们建立的 model,在按功能写py,大致如下
编辑model
models.py
# -*- coding=utf-8 -*- from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, relationship, backref from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, String, Integer, ForeignKey, DateTime # 用户名:密码@访问地址:端口/数据库?编码方式 engine = create_engine('mysql+mysqldb://root:***@***:***/website?charsite=utf8mb4') # 创建DBSession类型 DBSession = sessionmaker(bind=engine) # 创建Base基类 Base = declarative_base() class AdminUser(Base): # 超级用户表 __tablename__ = 'admin_user' # 表名 id = Column(Integer, primary_key=True) # 主键 username = Column(String(12), nullable=False, index=True, unique=True) # 用户名,Varchar12位,不可为空,常规索引 pwd = Column(String(256), nullable=False) # 密码,不可为空 token = Column(String(256), nullable=True) # token token_end_time = Column(DateTime, nullable=True) # token过期时间 class Vip(Base): # VIP用户 __tablename__ = 'vip' # 表名 id = Column(Integer, primary_key=True) # id name = Column(String(12), nullable=False, index=True, unique=True) # name pwd = Column(String(25), nullable=False) # pwd money = Column(Integer, nullable=False) # 金币 status = Column(Integer, nullable=False) # 账号状态(1:正常,0:封禁,2:审核) fk_vip_on_vip_lv = Column(Integer, ForeignKey('vip_lv.id'), nullable=False) # 关联VIPLV等级(多对一) VipLv = relationship('VipLv', backref=backref('Vip', uselist=True)) class VipInfo(Base): # VIP信息 __tablename__ = 'vip_info' # 表名 id = Column(Integer, primary_key=True) # id info = Column(String(256), nullable=True) # 备注,可为空 last_time = Column(DateTime, nullable=True) # 最后登陆时间,可为空 fk_vip_info_on_vip = Column(Integer, ForeignKey('vip.id'), unique=True, index=True, nullable=False) # 关联外键VIP.id(一对一) Vip = relationship('Vip', backref=backref('VipInfo', uselist=False)) # 设置关联使VIPInfo能查询到VIP class VipLv(Base): # VIP等级 __tablename__ = 'vip_lv' # 表名 id = Column(Integer, primary_key=True) # id lv = Column(Integer, nullable=False) # 等级 name = Column(String(25), nullable=False) # 等级名称 info = Column(String(256), nullable=False) # 等级说明 month_money = Column(Integer, nullable=True) # 月费 year_money = Column(Integer, nullable=True) # 年费 class VipOrder(Base): # VIP订单 __tablename__ = 'vip_order' # 表名 id = Column(Integer, primary_key=True) # id found_time = Column(DateTime, nullable=False) # 订单创建时间 check_status = Column(Integer, nullable=False) # 订单确认状态,1成功/0失败/2待确认/3已过期 err_info = Column(String(256), nullable=True) # 订单错误原因(订单错误时填写) success_time = Column(DateTime, nullable=True) # 订单确认时间 fk_vip_order_on_vip_lv = Column(Integer, ForeignKey('vip_lv.id'), nullable=False) # 关联外键VIP等级(多对一) VipLv = relationship('VipLv', backref=backref('VipLv', uselist=True)) money = Column(Integer, nullable=False) # 订单金额 go_time = Column(DateTime, nullable=False) # 开始时间 on_time = Column(DateTime, nullable=False) # 结束时间 # if __name__ == '__main__': # Base.metadata.create_all(engine)
初始化Flask-restful/蓝图
我们在 website下的 __init__中初始化 restful
# -*- coding=utf-8 -*- from flask import Blueprint from flask_restful import Api from .VIP import Vip, Token website_1_0 = Blueprint('website_1_0', __name__, url_prefix='/api/v1.0') # 生成蓝图,名称为website_1_0,设置蓝图下的统一前缀为/api/v1.0 api = Api(website_1_0) # 初始化api # 下方是添加路由控制 # api.add_resource(引入view的视图类, 匹配url) api.add_resource(Vip, '/website/vip/<int:vip_id>') # 获取VIP常用信息(匹配url带有int数字的传给Vip视图,url的参数命名为vip_id)
导入注册蓝图/restful
在app下的__init__.py中
# -*- coding=utf-8 -*- from flask import Flask from datetime import timedelta from flask_restful import Api # from flask_wtf.csrf import CsrfProtect from flask_cors import * # 导入模块 import datetime def create_app(): app = Flask(__name__) CORS(app, supports_credentials=True) # 设置跨域 # CsrfProtect(app) # from .website import website # app.register_blueprint(website) # from .website.views import VIP # VIP.init_app(app) from .website import api api.init_app(app) # restful需要initaoo from .website import website_1_0 app.register_blueprint(website_1_0) # 结合蓝图使用 return app
写Vip相关的视图类
vip.py
# -*- coding=utf-8 -*- from flask_restful import reqparse, abort, Api, Resource, request # from . import website from flask import render_template, Flask, request, redirect, url_for from app.website.models import DBSession, Vip, VipInfo, AdminUser, VipLv, VipOrder from ..tools import info_tool class Vip(Resource): # VIP信息(单) def get(self, vip_id): # 获取vip基本信息 from app.website.models import DBSession, Vip session = DBSession() obj = session.query(Vip).filter(Vip.id==vip_id).first() inf = info_tool.oneobj_to_safe(obj) # info_tool是我自己写的序列化 return inf
这样就能成功将其组合到一起了