赞
踩
官方文档
使用flask-appbuilder创建一个简单的项目,它是一个基于Flask的web框架,实现了数据的自动CRUD,登录等角色权限管理。
pip install flask-appbuilder # 帮助信息 flask --help flask routes # 查看所有的路由 flask run # 运行开发服务器 --help flask shell # 进入shell命令行 flask fab # fab 命令组 flask db upgrade # 同步数据库 flask fab --help # 帮助信息 babel-compile Babel, Compiles all translations babel-extract Babel, Extracts and updates all messages marked for... collect-static Copies flask-appbuilder static files to your... create-addon Create a Skeleton AddOn (needs internet connection... create-admin Creates an admin user create-app Create a Skeleton application (needs internet... create-db Create all your database objects (SQLAlchemy... create-permissions Creates all permissions and add them to the ADMIN... create-user Create a user export-roles Exports roles with permissions and view menus to... import-roles Imports roles with permissions and view menus from... list-users List all users on the database list-views List all registered views reset-password Resets a user's password security-cleanup Cleanup unused permissions from views and roles. security-converge Converges security deletes... version Flask-AppBuilder package version
使用flask fab管理命令,快速创建应用程序。
# 快速创建应用程序
flask fab create-app
# 输入项目名等
# __author__ = "laufing"
import os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# openssl rand -base64 42 生成秘钥
SECRET_KEY = "ulaO869huOl68ZhTZiNcOIq9zxwTSLd/LH40bv69IyUcb1xRssbAMrol"
SQLALCHEMY_DATABASE_URI = f"sqlite:///{BASE_DIR}/lauf.db"
# app 中
app/__init__.py
app = Flask(__name__)
app.config.from_object("config") #自动搜索config.py 进行配置
# views中
from flask_appbuilder import IndexView, BaseView
class MyIndexView(IndexView):
index_template = "tindex.html"
在_init_.py中导入定义的视图
from .views import *
# 获取数据库接口
db = SQLA(app)
appbuilder = AppBuilder(app, db.session, indexview=MyIndexView)
使用蓝图扩展用户模块,创建一个用户目录。
# user > 编写views.py from flask import request, session, current_app, g, jsonify from flask_appbuilder import BaseView, expose, has_access from app import appbuilder, db class UserView(BaseView): # 进入蓝图的基本路由 route_base = "/user" # 默认视图 default_view = "index" # 函数名,添加视图时,可以不指定href,请求时,匹配到default_view @expose("/index", methods=["GET"]) def index(self): return "用户首页" @expose("/api", methods=["GET"]) def get(self): return jsonify({ "name": "jack", "age": 12 }) @expose("/api", methods=["POST"]) def post(self): print("提交的数据:", request.form) return jsonify({ "token": "xyz123" }) # 添加视图、菜单 appbuilder.add_view(UserView, "user index", category="User View") # 没有href, 请求/user/index时走默认视图 appbuilder.add_view(UserView, "user menu", href="/user/api", category="User View") # 在 run.py (汇总) 中导入所有的视图 from app import app from user.views import * # 必须导入,或者在这里添加视图 app.run(host="0.0.0.0", port=5050, debug=True) # 设置环境变量 set FLASK_APP=run.py # 启动服务 # 代码更新,自动加载 --reload # 开启子线程 --with-reloads flask run -h localhost -p 5050 --reload --with-threads --debugger
浏览器中可以进行简单测试。
创建模型类
# user > models.py from flask_appbuilder import Model from sqlalchemy import Column, String, Integer class MyModel(Model): # 表名 __tablename__ = "my_model_t" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(50), unique=True, nullable=False) # print info when print this obj def __repr__(self): return self.name # 将模型类导入app.__init__.py db.create_all() # 创建所有的表
修改视图
,实现数据的插入、查询。
class UserView(BaseView): # 进入蓝图的前缀 route_base = "/user" # 默认视图 default_view = "index" # endpoint 函数名 @expose("/index", methods=["GET"]) def index(self): # 获取会话 session = db.session # db = SQLA(app) m_obj = session.query(MyModel).filter_by(id=1).one_or_none() # all()获取所有对象 print("result:", m_obj, type(m_obj)) return jsonify({ "status": 200, "id": m_obj.id, "name": m_obj.name }) @expose("/api", methods=["GET"]) def get(self): return redirect("/user/index") @expose("/api", methods=["POST"]) def post(self): print("提交的数据:", request.form) # requests.post(url, data=data) # 若requests.post(url, json=data) # request.json 属性 必须对应 name = request.form.get("name") session = db.session # 实例化数据对象 m = MyModel(name=name) # 添加到数据库 session.add(m) session.commit() return jsonify({ "status":200, "message": f"添加{name}成功" }) appbuilder.add_view(UserView, "user index", category="User View") appbuilder.add_view(UserView, "user view", href="/user/api", category="User View")
启动项目,可以进行简单测试。
get /user/api
post /user/api
from sqlalchemy import Column, String, Integer, PrimaryKey, Text, Date, Time, DateTime, create_engine from sqlalchemy.orm import relationship # 联系人的 分组表 main table class Group(Model): """ tablename: group_t fields: id, int pk name, varchar(30) unique not null """ __tablename__ = "group_t" # 定义关系时使用,默认的表名为模型类小写 + _ id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(30), unique=True, nullable=False) # 主表定义关系 # concat_relation = relationship("Concat", backref="concats", uselist=False) # 联系人 表 sub table class Concat(Model): """ table name: concat_t fields: id, int pk name, varchar(50) unique not null phone, varchar(11) not null group_id, int fk """ # table name __tablename__ = "concat_t" # primary key id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(50), unique=True, nullable=False, doc="姓名") phone = Column(String(11), nullable=False, doc="手机号") # foreign key # fk reference main table group_id = Column(Integer, ForeignKey("group_t.id")) # 引用 主表名.id # 定义关系 # Group为主表模型类 # backref 反向查询的名字 group = relationship("Group", backref="concats", uselist=False) def __repr__(self): return self.name
将模型类导入app._init_.py, 重启项目即可创建出所有的表。
在flask shell 下可以进行简单测试:
>>> from app import db >>> from user.models import Group, Concat >>> grp1 = Group(id=1, name="家人") >>> session = db.session # 自动开启事务 >>> session.add(grp1) >>> session.commit() >>> c1 = Concat(id=1, name="b1", phone="17446534545", group_id=1) >>> c2 = Concat(id=2, name="b2", phone="17876543454", group_id=1) >>> session.add(c1) >>> session.add(c2) >>> session.commit() # 返回查询 >>> grp1.concats [b1, b2] # 正向查询 >>> c1.group/group_id <user.models.Group object at 0x00000215A0ECA100> >>> c1.group.name '家人'
可在视图中自己实现CRUD, 略
基于flask_appbuilder 实现自动的CRUD,定义模型类视图。
from flask_appbuilder import ModelView from flask_appbuilder.models.sqla.interface import SQLAInterface from .models import Group, Concat class ConcatModelView(ModelView): # 管理后台页面 datamodel = SQLAInterface(Concat) # 定义 视图页面显示的列名称 label_columns = {'group_id': 'Concats Group ID', "name": "Concat Name"} # 列表视图 显示的列 /concatmodelview/list/ list_columns = ["id", "name", "phone", "group_id"] # show视图(一条数据) 显示的列 /concatmodelview/show/pk show_columns = ["id", "name"] # 搜索字段 search_columns = ['name',] # show 视图展示的格式 /concatmodelview/show/1 优于show_columns show_fieldsets = [ ( # 每一部分都是一个元祖 'Summary1111111', # 标题 {'fields': ['name', 'group_id']} ), ( 'Personal Info', {'fields': ['phone',], 'expanded': False} ), ] class GroupModelView(ModelView): datamodel = SQLAInterface(Group) # input a model related_views = [ConcatModelView] # 添加 模型视图 自动路由 appbuilder.add_view(GroupModelView, "Group menu", category="GroupModelView", icon = "fa-folder-open-o") appbuilder.add_view(ConcatModelView, "Concat menu", category="ConcatModelView", icon = "fa-envelope") # 为ConcatModelView 自动添加的路由 # flask_appbuilder.base:Registering class ConcatModelView on menu Concat menu # flask_appbuilder.baseviews:Registering route /concatmodelview/action/<string:name>/<pk> ['GET', 'POST'] # flask_appbuilder.baseviews:Registering route /concatmodelview/action_post ['POST'] # flask_appbuilder.baseviews:Registering route /concatmodelview/add ['GET', 'POST'] 添加 页面 # flask_appbuilder.baseviews:Registering route /concatmodelview/api ['GET'] api返回所有联系人的json数据 # flask_appbuilder.baseviews:Registering route /concatmodelview/api/column/add/<col_name> ['GET'] # flask_appbuilder.baseviews:Registering route /concatmodelview/api/column/edit/<col_name> ['GET'] # flask_appbuilder.baseviews:Registering route /concatmodelview/api/create ['POST'] 添加一个联系人 # flask_appbuilder.baseviews:Registering route /concatmodelview/api/delete/<pk> ['DELETE'] 删除一个联系人 # flask_appbuilder.baseviews:Registering route /concatmodelview/api/get/<pk> ['GET'] 获取一个联系人 # flask_appbuilder.baseviews:Registering route /concatmodelview/api/read ['GET'] 获取所有联系人 json # flask_appbuilder.baseviews:Registering route /concatmodelview/api/readvalues ['GET'] 获取少许字段 # flask_appbuilder.baseviews:Registering route /concatmodelview/api/update/<pk> ['PUT'] 更新一个 # flask_appbuilder.baseviews:Registering route /concatmodelview/delete/<pk> ['GET', 'POST'] 删除一个 # flask_appbuilder.baseviews:Registering route /concatmodelview/download/<string:filename> ('GET',) # flask_appbuilder.baseviews:Registering route /concatmodelview/edit/<pk> ['GET', 'POST'] 编辑联系人页面 # flask_appbuilder.baseviews:Registering route /concatmodelview/list/ ('GET',) 视图页面 # flask_appbuilder.baseviews:Registering route /concatmodelview/show/<pk> ['GET'] 视图页面
show_fieldsets
add_fieldsets、edit_fieldsets,可以自定义显示的字段格式。
对模型视图
的CRUD必须登录。
启动服务,测试增删改查。
# 设置环境变量
set FLASK_APP=run.py
# flask run --help
flask run -h localhost -p 5050 --reload --with-threads
浏览器中访问 http://localhost:5050 加对应的路由地址,综合测试。
# 使用pip包管理工具,安装到python环境中
pip install gunicorn
# 安装协程并发库,linux下需要安装apt install python-dev libevent
pip install gevent eventlet
另外也可以使用源码安装。
Ubuntu 20.04默认仓库就带有gunicorn,可以如下直接安装:
$ sudo apt-get update
$ sudo apt-get install gunicorn
# config_gunicorn.py 它是一个python文件
# 绑定主机地址
bind='0.0.0.0:8000' # 局域网ip 或者公网内的局域网
# 注意没有port选项
# 开启三个worker进程
gunicorn -w 3 -b 0.0.0.0:8000 my_flask_project.app:app
# 使用.表示路径,找到对应的模块
# 使用:拼接模块中的app对象
# 也可以my_flask_project.app:create_app() 工厂函数执行
# 默认加载当前目录下的gunicorn.conf.py
# 创建一个配置文件
# config_gunicorn.py 命令行-c xxxconfig.py 指定配置文件
bind='0.0.0.0:8000' # 绑定ip地址 命令行下用--bind ip:port
daemon='true' # 后台启动 命令行 --daemon
worker_class='gevent' # worker进程的类型 命令行下 -k
workers=4 # 开启4个worker进程
threads=4 # 每个worker进程中4个线程
# 日志输出
loglevel='info'
accesslog='logs/access.log'
errorlog='logs/error.log'
启动flask
# 使用gunicorn启动flask应用
gunicorn -c config_gunicorn.py package.module:app
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。