Flask AppBuilder 详解
官方:https://flask-appbuilder.readthedocs.io/en/latest/cli.html#create-app-create-new-applications安装pip install flask-appbuilder命令行启动fabmanager 命令不再使用,新版本使用Flask cli集成的新命令行管理器。不过命令形式和参数是一样的。也就是使用fl...
全栈工程师开发手册 (作者:栾鹏)
python教程全解
官方:https://flask-appbuilder.readthedocs.io/en/latest/cli.html#create-app-create-new-applications
安装
pip install flask-appbuilder
命令行启动
fabmanager 命令不再使用,新版本使用Flask cli集成的新命令行管理器。不过命令形式和参数是一样的。也就是使用flask fab代替原来命令中的fabmanager
mac os先要安装证书的包
cd "/Applications/Python 3.6/"
sudo "./Install Certificates.command"
开始使用命令行flask fab的参数如下(可以通过flask fab --help
查看)
babel-compile-Babel,编译所有翻译
babel-extract-Babel,提取和更新所有消息。
create-admin-创建一个管理员用户
create-user-创建具有任意角色的用户
create-app-创建一个骨架应用程序(SQLAlchemy或MongoEngine)。
create-addon-创建骨架插件。
create-db-创建所有数据库对象(仅适用于SQLAlchemy)
collect-static-将静态文件从flask-appbuilder复制到您的静态文件夹。很高兴在某些部署上
list-users-列出数据库中的所有用户。
list-views-列出所有注册的视图。
reset-password-重置用户密码。
security-cleanup -从视图和角色清除未使用的权限。安全
security-converge-融合来自所有角色的所有安全性视图和权限名称。安全
upgrade-db-在FAB升级后升级数据库。
version -Flask-AppBuilder软件包版本。
使用命令行快速生成项目结构
flask fab create-app
创建admin用户
cd myapp
flask fab create-admin # 会在ab_user中添加用户并绑定权限
现在,我们已经有一个基本的web后台了,下面我们来运行一下,进行查看效果。
启动
flask run --with-threads --reload # 如果使用 flask run 命令启动,将忽视.py文件里配置8080,而采用默认的5000端口
或者
python run.py
之后我们在浏览器上输入127.0.0.1:8080就可以看到生成的页面。
model 修改后需要 升级数据库
flask db migrate
flask db update
config.py
config.py文件时fab的公共配置。
配置参考官网:https://flask-appbuilder.readthedocs.io/en/latest/config.html
其中系统配置
app的名字
APP_NAME = "My App Name"
# 配置连接数据库
配置SQLALCHEMY_DATABASE_URI的值来指定数据库连接。如果使用Mongdb可以配置MONGODB_SETTINGS的值。默认使用Sqlite数据库,SQLALCHEMY_DATABASE_URI的值为'sqlite:///' + os.path.join(basedir, 'app.db')。
设置为mysql
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:admin@localhost:3306/myapp'
# 通过配置AUTH_TYPE来指定应用使用的认证方式。
AUTH_TYPE = 0 | 1 | 2 | 3 | 4或AUTH_TYPE = AUTH_OID, AUTH_DB,AUTH_LDAP, AUTH_REMOTE AUTH_OAUTH。默认使用AUTH_DB的认证方式。
# 配置主题风格
Flask-AppBuilder集成了bootwatch,只需要配置APP_THEME的值就可以改变应用的主题风格。
配置主题风格
APP_THEME = "spacelab.css"
# 配置身份验证类型
AUTH_TYPE = AUTH_DB #AUTH_OID,AUTH_DB,AUTH_LDAP,AUTH_REMOTE AUTH_OAUTH
配置自己的首页
我们在/app下创建文件index.py,并且输入下面内容:
from flask_appbuilder import IndexView
class MyIndexView(IndexView):
index_template = 'index.html'
接着在templates中index.html文件,在其中定义你想要的首页的内容。
{% extends "appbuilder/base.html" %}
{% block content %}
<div class="jumbotron">
<div class="container">
<h1>{{_("My App on F.A.B.")}}</h1>
<p>{{_("My first app using F.A.B, bla, bla, bla")}}</p>
</div>
</div>
{% endblock %}
最后修改app/__iniy__.py
的内容,在AppBuilder初始化的时候,指定indexview的值
from app.index import MyIndexView
appbuilder = AppBuilder(app, db.session, indexview=MyIndexView) # 替换原来的初始化语句
AppBuilder类可以指定数据库,模板目录,静态文件目录,静态文件url,安全管理,菜单等
添加视图/将视图添加到菜单
BaseView是视图中的基类,所有的视图都继承自它。当我们定义一个继承自BaseView的子类时,BaseView自动将我们用@exposed修饰的urls注册为Flask中的蓝图。我们可以通过BaseView来实现自定义页面,并添加到菜单上或者通过一个连接来访问它。这里需要注意,作为路由的方法一定要用@exposed修饰,如果需要保护的路由则需要额外使用@has_access修饰。 现在我们来看一个小例子,通常我们使用F.A.B.框架都使用自动生成的项目结构,这样我们只需要在app目录下views.py文件中修改代码即可。下面我们来看一个简单例子:
from flask_appbuilder import ModelView,AppBuilder,expose,BaseView,has_access
# 一个蓝图
class indexView(BaseView):
# 相对路径的url
route_base = '/index' # 蓝图前缀路由
default_view = 'hello' # 设置进入蓝图的默认访问视图(没有设置网址的情况下)
# 新视图,蓝图url+路由
@expose('/hello')
def hello(self):
return 'Hello World'
# 新视图,蓝图url+路由
@expose('/message/<string:msg>')
@has_access
def message(self, msg):
msg = 'Hello' + msg
# 返回模板
return self.render_template('hello.html',msg=msg)
# 后端添加视图,同时前端添加菜单
appbuilder.add_view(indexView,'Hello',category='My View') # 使用默认视图
# 前端,向菜单栏添加子菜单,绑定链接
appbuilder.add_link('message',href='/index/message/user',category='My View')
# 前端,向菜单栏添加子菜单,绑定链接
appbuilder.add_link('welcome',href='/index/hello',category='My View')
# 添加一个后端视图,不添加前端菜单
# appbuilder.add_view_no_menu(indexView())
如果想渲染的html模板跟默认模板一样需要继承appbuilder/base.html
在’/app/templates/'目录中,创建一个hello.html,并添加下面的代码
{% extends "appbuilder/base.html" %}
{% block content %}
<h1>Welcome</h1>
<h2>Hello World</h2>
<h3>{{ msg }}</h3>
{% endblock %}
此时我们再访问http://127.0.0.1:8080就需要登录之后才可以进行访问
自定义model/将model添加到前端视图
定义表的时候需要继承Model类。
修改/app/models.py这个文件,添加
from sqlalchemy import Column, Integer, String, ForeignKey ,Date
from flask_appbuilder.models.decorators import renders
from flask import Markup
#定义联系人分组,如家人、同学
class ContactGroup(Model):
id = Column(Integer, primary_key=True)
name = Column(String(50), unique = True, nullable=False)
def __repr__(self):
return self.name
# 定义联系人
class Contact(Model):
id = Column(Integer, primary_key=True)
name = Column(String(150), unique = True, nullable=False)
address = Column(String(564))
birthday = Column(Date)
personal_phone = Column(String(20))
personal_cellphone = Column(String(20))
contact_group_id = Column(Integer, ForeignKey('contact_group.id')) # 定义外键,绑定联系人所属分组
contact_group = relationship("ContactGroup")
def __repr__(self):
return self.name
# 自定义一个函数字段和渲染样式,供前端显示
@renders('name')
def my_name(self):
return Markup('<b style="color:red">' + self.name + '</b>')
为model生成前端视图
通过继承ModelView类可以实现我们自定义的视图,F.A.B.可以针对我们定义好的数据库模型生成创建、删除、更新和显示的功能。
每个model视图,在前端会包含添加新记录,list,查看单条详情,修改几个界面。我们可以配置下面几个参数来实现配置这几个界面。
- label_columns:用于定义model的列在前端显示时的别名(因为model的列一般写成英文,在前端显示时我们一般设置为中文别名)
- list_columns:用于定义list页面中要显示的字段。
- show_fieldsets:用于定义查看记录详情页面中显示的内容,还可以单独定义 add_fieldsets 和 edit_fieldsets页面中的内容。
编辑 /app/views.py 文件
# 将model添加成视图,并控制在前端的显示
from .models import Contact,ContactGroup
from flask_appbuilder.actions import action
from flask import redirect
from flask_appbuilder.models.sqla.filters import FilterEqualFunction, FilterStartsWith,FilterEqual,FilterNotEqual
from wtforms.validators import EqualTo,Length
from flask_babel import lazy_gettext,gettext
from flask_appbuilder.security.decorators import has_access
# 定义数据库视图
class ContactModelView(ModelView):
datamodel = SQLAInterface(Contact)
# 定义创建页面要填写的字段
add_fieldsets=[
(
'Summary',
{'fields': ['name','personal_phone','contact_group']}
)
]
# 定义编辑页面要填写的字段
edit_fieldsets = [
(
'Summary',
{'fields': ['name', 'address','birthday','personal_phone','personal_cellphone', 'contact_group']}
)
]
# 定义在前端显示时,model的列,显示成一个新别名
label_columns = {'name':'姓名','my_name':"姓名",'contact_group':'分组'}
#定义前端model list页面显示的列。my_name为自定义样式的一列
list_columns = ['my_name','personal_cellphone','birthday','contact_group']
# 定义单条model记录详情显示的列
show_fieldsets = [
(
'Summary',
{'fields':['name','address','contact_group']}
),
(
'Personal Info',
{'fields':['birthday','personal_phone','personal_cellphone'],'expanded':False}
),
]
# 定义list页面的默认筛选条件的配置
base_filters = [['name', FilterNotEqual, ''],] # 筛选出名称为''的
# 定义list页面的排序方法
base_order = ('id', 'dasc')
# 使用自定义模板配置详情页面
# extra_args = {'name': 'SOMEVALUE'}
# show_template = 'my_show_template.html'
# 自定义add/update页面时表单提交自动校验
validators_columns = {
'personal_phone': [Length(min=11,max=11, message=gettext('fields length mush 11'))] # message 为错误时的提示消息
}
# 为关联字段做自定义查询过滤器。add_form_quey_rel_fields、edit_form_query_rel_fields、search_form_query_rel_fields
add_form_query_rel_fields = {'contact_group': [['name', FilterStartsWith, '家']]} # 仅能选择 name字段的值以'家'开头的contact_group。
# 自定义 页面模板
# show_template = 'appbuilder/general/model/show_cascade.html'
# edit_template = 'appbuilder/general/model/edit_cascade.html'
# 在联系人组视图中,我们使用related_views来关联联系人视图,F.A.B.将自动处理他们之间的关系。包含列表显示列,修改列
class GroupModelView(ModelView):
datamodel = SQLAInterface(ContactGroup)
related_views = [ContactModelView]
base_permissions = ['can_add','can_edit', 'can_delete','can_list','can_show'] # 默认为这些
# 自定义model视图中的操作按钮。会在数据库添加权限,和视图-权限绑定。
# 默认在model的list页面以list形式调用该函数,在详情页面以单记录形式调用该函数。single=False固定仅在list页面显示该按钮。
@action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False)
@has_access # 为方法启动权限保护
def muldelete(self, items):
if isinstance(items, list):
self.datamodel.delete_all(items)
self.update_redirect()
else:
self.datamodel.delete(items)
return redirect(self.get_redirect())
# 首先使用db.create_all()根据数据库模型创建表,然后再将视图添加到菜单。
db.create_all()
appbuilder.add_view(GroupModelView,"List Groups",icon = 'fa-address-book-o',category = 'Contacts',category_icon = 'fa-envelope')
appbuilder.add_separator("Contacts") # 在指定菜单栏下面的每个子菜单中间添加一个分割线的显示。
appbuilder.add_view(ContactModelView,'List Contacts',icon = 'fa-address-card-o',category = 'Contacts')
添加后台api
在view.py中添加自定义的后端接口
# 添加自定义后端接口
from flask import request
from flask_appbuilder.api import BaseApi, expose, rison, safe # rison 是和json类似更简单的map数据格式
from flask_appbuilder.security.decorators import protect,permission_name
from . import appbuilder
# BaseApi 类包含了所有的公开方法
class ExampleApi(BaseApi):
resource_name='example'
version='v1'
base_permissions=['can_get'] # 该视图类会自动添加的权限绑定
class_permission_name=['ExampleApi'] # 该视图类被添加为视图时的名称
# route_base = '/newapi/v2/nice' # 覆盖基础路由/api/{version}/{resource_name},默认是api/v1/$classname_lower
# expose 注册为蓝图,url为http://localhost:5000/newapi/v2/nice/greeting
@expose('/greeting', methods=['POST', 'GET'])
def greeting(self):
if request.method == 'GET':
return self.response(200, message="Hello (GET)")
return self.response(201, message="Hello (POST)")
# 编写受权限控制的视图
# 访问该接口,需要携带token. -H "Authorization: Bearer $TOKEN".
# token获取:
# curl -XPOST 'http://localhost:8080/api/v1/security/login'
# -d '{"username": "root", "password": "admin", "provider": "db"}'
# -H "Content-Type: application/json"
@expose('/private')
@protect() # 为api启动权限保护。 会在数据库中新建一个can_rison_json的权限,并在视图上建一个这样的视图-权限绑定
@permission_name('my_Permission') # 自定义权限名称,而不使用默认的函数名为权限名
def rison_json(self):
return self.response(200, message="This is private")
@expose('/error')
@safe # 使用safe装饰器正确处理所有可能的异常,它将为您捕获所有未捕获的异常并返回正确的错误响应
def error(self):
raise Exception
appbuilder.add_api(ExampleApi)
为model 添加rest api接口
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.api import ModelRestApi
from . import appbuilder
class GroupModelApi(ModelRestApi):
resource_name = 'group'
datamodel = SQLAInterface(ContactGroup)
# 该api自动生成,下面的api和绑定权限,需要有此权限的角色才能调用api
# /_info get can_info
# / get,post创建记录 can_get,can_post,can_put
# /<id> get读取记录,delete删除记录,put修改记录 can_get,can_delete
appbuilder.add_api(GroupModelApi)
chart 视图的使用
BaseChartView为谷歌图表,前端页面显示时需要连接谷歌。
DirectChartView,GroupByChartView,ChartView,TimeChartView 均继承自BaseChartView
定义一个model
# charts视图的model
from sqlalchemy import Column, Integer, String, ForeignKey,Float
import datetime
# insert into country (name) values ('china')
# insert into country_stats (stat_date,population,unemployed_perc,poor_perc,college,country_id) values ('2019-10-11',100,10,10,30,1), ('2019-11-11',110,9,10,30,1), ('2019-12-11',120,8,10,30,1)
class Country(Model):
id = Column(Integer, primary_key=True)
name = Column(String(50), unique = True, nullable=False)
def __repr__(self):
return self.name
class CountryStats(Model):
id = Column(Integer, primary_key=True) # 国家历史状态id
stat_date = Column(Date, nullable=True) # 当时的时间
population = Column(Float) # 当时的人口总数
unemployed_perc = Column(Float) # 失业人口比例
poor_perc = Column(Float) # 当时的贫困者比例
college = Column(Float) # 当时的大学生总数
country_id = Column(Integer, ForeignKey('country.id'), nullable=False) # 国家id
country = relationship("Country")
# 定义函数计算全国失业人数/全国大学生
def college_perc(self): # 函数可以作为一个字段对后端接口使用,像查询列一样获取数据
if self.population != 0:
return (self.college * 100) / self.population
else:
return 0.0
# 定义时间新字段
def month_year(self):
return datetime.datetime(self.stat_date.year, self.stat_date.month, 1)
DirectChartView
添加视图代码
from flask_appbuilder.charts.views import DirectByChartView
from flask_appbuilder.models.sqla.interface import SQLAInterface
from .models import CountryStats
class CountryDirectChartView(DirectByChartView):
datamodel = SQLAInterface(CountryStats)
# 每个chart包含过滤(查询数据源)和报表可视化显示两部分
chart_title = 'Direct Data Example'
chart_type = 'ColumnChart' # 图表类型 PieChart,ColumnChart或LineChart
# 定义报表部分前端页面的相关显示。多个图表,每个图表包含多个曲线数据。
definitions = [
{
'label': 'Unemployment', # 当前图表的标题
'group': 'stat_date', # 用来作为x的字段。
'series': ['unemployed_perc','college_perc'] # 用来作为y的字段,包含多个y值
},
{
'label': 'Poor',
'group': 'stat_date',
'series': ['poor_perc','college_perc']
}
]
appbuilder.add_view(CountryDirectChartView, "Show Country Chart", icon="fa-dashboard", category="Statistics")
分组图表的使用
# 分组图表的使用
from flask_appbuilder.charts.views import GroupByChartView
from flask_appbuilder.models.group import aggregate_count, aggregate_sum, aggregate_avg # 分组计算函数
from flask_appbuilder.models.sqla.interface import SQLAInterface
import calendar
from .models import CountryStats
from .models import Country
class CountryGroupByChartView(GroupByChartView):
datamodel = SQLAInterface(CountryStats)
chart_title = 'Statistics'
definitions = [
{
'label': 'Country Stat',
'group': 'month_year', # x的取值字段
'formatter': lambda value:calendar.month_name[value.month] + ' ' + str(value.year), # x值的显示格式
'series': [(aggregate_avg, 'unemployed_perc'), # 分组后,指定字段值集合进行计算后再显示
(aggregate_avg, 'population'),
(aggregate_avg, 'college_perc')
]
}
]
appbuilder.add_view(CountryGroupByChartView, "Show group Country Chart", icon="fa-dashboard", category="Statistics")
后端代码对数据库的影响
- 在后端添加的add_api的viewclass/add_view中的viewclass,name/add_link中的name,category 等都会在ab_view_menu表中中添加为视图,注意并不是每个视图函数或网址接口都添加为视图。
@protect()
和@has_access
修饰的视图函数,或在ab_permission中生成can_viewname的权限,并且创建在该视图上的该权限的绑定。只有有此权限绑定的角色才能调用这个视图。
自定义模板
您可以添加自己的js,css,导航栏模板,list,add,edit,show,edit-related级联页面模板,参考:https://flask-appbuilder.readthedocs.io/en/latest/templates.html#css-and-javascript
appbuilder自带的安全权限
支持的身份验证方式
- Database验证:从数据库查询要匹配的用户名和密码样式。密码在数据库中保持散列。
- Open ID方式验证:使用用户的电子邮件字段在Gmail,Yahoo等上进行身份验证。使用Flask-Login保留并加密会话,OpenID需要Flask-OpenID
- LDAP方式验证:针对LDAP服务器(例如Microsoft Active Directory)的身份验证
- REMOTE_USER方式:读取REMOTE_USER Web服务器environ var,并验证它是否已获得框架用户表的授权。当服务器(Apache,Nginx)配置为使用kerberos时,Web服务器负责对用户进行身份验证,这对于Intranet站点很有用,无需用户在FAB上使用用户名和密码登录
- OAUTH方式验证:使用OAUTH(v1或v2)进行身份验证。您需要安装flask-oauthlib。三方服务器授权层,授权Flask AppBuilder一个token,Flask AppBuilder使用这个token获取三方服务器上的数据。
# 在配置文件中配置身份验证类型
AUTH_TYPE = AUTH_DB #AUTH_OID,AUTH_DB,AUTH_LDAP,AUTH_REMOTE AUTH_OAUTH
每种认证方式的配置参考:https://flask-appbuilder.readthedocs.io/en/latest/security.html#authentication-methods
自定义身份认证方式
由于user不仅牵扯到认证授权,还有model的增删改查,所以如果我们自定义认证方式,需要和系统自带的user-model联系在一起,既能保证自定义认证,又能保证原有的user在数据库中的增删改查。
认证和user-model是两个模块组成的。
在config.py文件中添加
# 自定义认证方式的user model。继承usermodel,因为也是需要在数据库中存储和查询的。
class MyUserDBView(UserDBModelView):
@action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False)
def muldelete(self, items):
self.datamodel.delete_all(items)
self.update_redirect()
return redirect(self.get_redirect())
# 自定义认证策略
class MySecurityManager(SecurityManager):
userdbmodelview = MyUserDBView
FAB_SECURITY_MANAGER_CLASS=MySecurityManager
FAB为每种身份验证方法使用不同的用户视图
- UserDBModelView:对于数据库身份验证方法
- UserOIDModelView:对于开放ID身份验证方法
- UserLDAPModelView:对于LDAP身份验证方法
当然我们可以扩展系统自带的user model
- AUTH_DB: 扩展UserDBModelView
- AUTH_LDAP: 扩展UserLDAPModelView
- AUTH_REMOTE_USER:扩展UserRemoteUserModelView
- AUTH_OID: 扩展UserOIDModelView
- AUTH_OAUTH: 扩展UserOAuthModelView
一种方式是直接在config.py文件中
# 自定义扩展系统自带的user
class MyUser(User):
__tablename__ = 'ab_user'
extra = Column(String(256)) # 新增的属性
# 自定义认证方式的user model。继承usermodel,因为也是需要在数据库中存储和查询的。
class MyUserDBView(UserDBModelView):
@action("muldelete", "Delete", "Delete all Really?", "fa-rocket", single=False)
def muldelete(self, items):
self.datamodel.delete_all(items)
self.update_redirect()
return redirect(self.get_redirect())
# 自定义认证策略
class MySecurityManager(SecurityManager):
user_model = MyUser
userdbmodelview = MyUserDBView
FAB_SECURITY_MANAGER_CLASS=MySecurityManager
一种方式是单独定义扩展model的py文件,单独定义扩展view的文件,然后在__init__.py
文件中添加自定义认证方法
from flask_appbuilder.security.sqla.manager import SecurityManager
from .sec_models import MyUser
from .sec_views import MyUserDBModelView
class MySecurityManager(SecurityManager):
user_model = MyUser
userdbmodelview = MyUserDBModelView
# appbuilder = AppBuilder(app, db.session, indexview=MyIndexView,menu=Menu(reverse=False),base_template='mybase.html',security_manager_class=MySecurityManager)
Flask AppBuilder自带的所有视图类
- BaseView: 收集所有公开的方法,创建Flask蓝图并注册URL,初始化基本权限。
- UtilView: 实现公开的背面以实现特殊的背面UI功能。
- IndexView: 呈现index页面的特殊视图。
- SimpleFormView: 对其进行子类化以呈现WTForms。
- PublicFormView: 与SimpleFormView相同,但仅具有公共访问权限。
- BaseModelView: 负责初始数据模型层的类,实现搜索表单和过滤器。
- BaseChartView: 基本图表视图功能。
- GroupByChartView:对其进行子类化,以按查询分组显示Google图表。
- DirectByChartView:对其进行子类化以呈现带有查询的Google图表。
- BaseCRUDView: 实现基本功能以添加,编辑,删除,创建所有表单。
- RestCRUDView: 公开用于CRUD方法的JSON REST API等。
- ModelView: 对其进行子类化,以基于模型呈现您的视图,并具有完整的CRUD UI功能。
- MasterDetailView:渲染与数据库有关一个主模型视图和多个细节模型视图。
- MultipleView: 在同一页面上呈现多个视图(例如:ModelView和GroupByChartView)
Flask AppBuilder自带的用于数据库访问的类
- BaseInterface: 接口类,为数据访问强加了唯一的API层。
- SQLAInterface: SQLAlchemy的数据访问。
- MongoEngineInterface:MongoEngine(MongoDB)的数据访问。
- GenericInterface: 自定义数据结构的数据访问。
Flask AppBuilder 中 Security相关的类
- BaseManager: 所有Manager类的基类都包含AppBuilder类。
- AbstractSecurityManager:安全管理器的抽象类,定义必须具有的方法。
- BaseSecurityManager:安全性的基类,注册安全性视图,实现身份验证,插入/删除数据库上的所有权限,管理角色/用户和视图。
- sqla.SecurityManager:为SQAlchemy实现BaseSecurityManager。
- mongoengine.SecurityManager:为MongoEngine实现BaseSecurityManager。
用户、角色、权限、视图之间的关系
每个用户可能具有多个角色,并且一个角色拥有对视图/ API和菜单的权限,因此产生了用户对视图/ API和菜单具有权限。
配置文件中配置自带的角色
格式为
FAB_ROLES = {
"<ROLE NAME>": [
["<VIEW/MENU/API NAME>", "PERMISSION NAME"],
....
],
...
}
示例
# 添加自带角色和具有的视图-权限
FAB_ROLES = {
"ReadOnly": [
[".*", "can_list"],
[".*", "can_show"],
[".*", "menu_access"],
[".*", "can_get"],
[".*", "can_info"]
]
}
# 修改之前的角色id,为新的角色名称。自带Admin和Public不能替换名称。
# FAB_ROLES_MAPPING = {
# 3: "role1"
# }
权限
Flask AppBuilder 自动为视图、API或菜单,创建所有可能的现有权限。
每次基于模型(从ModelView继承)创建新视图时,都会创建以下权限:
- can list
- can show
- can add
- can edit
- can delete
- can download
对于CRUD REST API:
- can get
- can put
- can post
- can delete
- can info
除了创建权限,还会创建在这些自定义视图上的权限绑定记录。因为权限都是在视图上才有意义。
如果我们想在视图类上创建访问视图函数的权限。使用@has_access
修饰我们的视图函数(在api类上使用@protect()
修饰)。那么框架将根据您的视图函数名称创建权限,并添加MyModelView上的mymethod,这个视图-权限绑定对。
可以使用@permission_name
自定义权限名称,而采用默认的视图函数名作为权限名称。
上面的权限过于精细化,当视图过多时非常麻烦,可以将权限进行合并。
- 使用class_permission_name直接对一个类里面的所有方法统一设置权限。将多个方法合并设置
- 使用method_permission_name对多种权限统一设定。将多种权限统一设定
class OneApi(ModelRestApi):
datamodel = SQLAInterface(Contact)
class_permission_name = "api"
method_permission_name = {
"get_list": "access",
"get": "access",
"post": "access",
"put": "access",
"delete": "access",
"info": "access"
}
# 修改之前的权限名称。如果之前的名称是get,就换成最新的access
previous_method_permission_name = {
"get_list": "get",
"get": "get",
"post": "get",
"put": "get",
"delete": "get",
"info": "get"
}
获取的视图和权限为
can access on api
清理之前的垃圾视图和权限
# 修改代码后,视图/权限名称变更,会在数据库中生成新的记录,旧记录删除需要下面的语句。
appbuilder.security_cleanup()
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)