flask- admin

Posted 哈士骑KT猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flask- admin相关的知识,希望对你有一定的参考价值。

文档:https://flask-admin.readthedocs.io/en/latest/


1. FLASK-Admin

1.1 安装

pip install flasf-admin
或者
conda install flask-admin -c conda-forge

1.2 模块初始化

application/__init__.py,代码:

# 项目初始化[主程文件]
import os
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommand
from flask_jsonrpc import JSONRPC
from faker import Faker
from flask_jwt_extended import JWTManager
from flask_admin import Admin

from application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command
from application.utils import init_blueprint
from application.utils.language.message_text import Message as message
from application.utils.language.status_number import Status as status
# 创建数据库链接对象
db = SQLAlchemy()

# redis链接对象
redis = FlaskRedis()

# Session存储对象
session_store = Session()

# 数据迁移实例对象
migrate = Migrate()

# 日志对象
log = Log()

# 初始化jsonrpc模块
jsonrpc = JSONRPC(service_url=\'/api\')

faker = Faker(locale="zh_CN")

# jwt认证模块实例化
jwt = JWTManager()

# flask-admin模块初始化
admin = Admin()

def init_app(config_path):

    app = Flask(__name__)

    # 项目根目录
    app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # import sys
    # sys.path.append(os.path.join(app.BASE_DIR, "application/utils/language"))
    # 加载配置
    app.config.from_object(load_config(config_path))

    # 初始化终端脚本工具
    manager = Manager()
    manager.app = app

    # 数据库
    db.init_app(app)
    redis.init_app(app)

    # session存储初始化
    init_session(app)
    session_store.init_app(app)

    # 数据迁移初始化
    migrate.init_app(app,db)
    # 添加数据迁移的命令到终端脚本工具中
    manager.add_command(\'db\', MigrateCommand)

    # 日志初始化
    app.log = log.init_app(app)

    # 注册自定义命令
    load_command(manager)

    # 初始化json-rpc
    app.jsonrpc = jsonrpc
    jsonrpc.init_app(app)

    # jwt初始化
    jwt.init_app(app)

    # 注册蓝图
    init_blueprint(app)

    # admin站点
    admin.init_app(app)
    admin.name = app.config[\'FLASK_ADMIN_NAME\']
    admin.template_mode = app.config[\'TEMPLATE_MODE\']

    return manager

settings/__init__,代码:

    # 运营站点配置信息
    FLASK_ADMIN_SWATCH = \'cerulean\'
    FLASK_ADMIN_NAME = "魔方App"
    TEMPLATE_MODE = "bootstrap3"

直接访问效果如下:
image

可以发现上面什么都没有,就一个Home首页导航.

测试代码,我们可以在users的任意一个文件中,编写一段官方提供的基于模型生成后台视图功能的代码,这里我们先写在users.urls里面。

from . import views
from application.utils import api


jsonpatterns = [
    api("mobile",views.check_mobile),
    api("register",views.register),
    api("refresh", views.refresh ),
    api("login", views.login ),
    api("info", views.info ),
]

from application import admin,db
from .models import User
from flask_admin.contrib.sqla import ModelView
admin.add_view(ModelView(User, db.session)) 

访问admin后台,效果如下:
image


1.3 模块配置

因为后台站点的相关代码肯定很多,页面也多,所以我们把每一个蓝图下关于admin站点相关配置的代码编写在每一个蓝图下的admin.py 中,并且在蓝图初始化中进行自动加载.

application/utils/__init__.py,代码:

from importlib import import_module
from flask import Blueprint

def path(rule,view_func):
    # 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参
    return {"rule":rule,"view_func":view_func}

def include(url_prefix, blueprint_path):
    """把路由前缀和蓝图进行关系映射"""
    return {"url_prefix":url_prefix,"blueprint_path":blueprint_path}

def api(name,method):
    """把api接口访问别名和视图进行关系映射"""
    return {"name":name, "method":method}

def init_blueprint(app):
    """自动注册蓝图"""
    # 读取蓝图列表
    blueprint_path_list = app.config.get("INSTALLED_APPS")
    # 读取总路由文件
    url_path = app.config.get("URL_PATH")
    urlpatterns = import_module(url_path).urlpatterns  # 加载蓝图下的子路由文件

    for blueprint_path in blueprint_path_list:
        blueprint_name = blueprint_path.split(".")[-1]
        # 自动创建蓝图对象
        blueprint = Blueprint(blueprint_name, blueprint_path)


        url_module = import_module("%s.urls" % blueprint_path)
        # 注册路由和视图
        try:
            for urls in url_module.urlpatterns:
                blueprint.add_url_rule(**urls)
        except:
            pass

        # 注册rpc接口
        try:
            for api in url_module.jsonpatterns:
                app.jsonrpc.site.register(blueprint_name.title()+"."+api["name"],api["method"])
        except:
            pass

        # 添加蓝图的路由前缀
        url_prefix = ""  # 蓝图路由前缀
        for urlpattern in urlpatterns:
            if urlpattern["blueprint_path"] == blueprint_name+".urls":
                url_prefix = urlpattern["url_prefix"]
                break

        # 注册蓝图对象到app应用对象中
        app.register_blueprint(blueprint, url_prefix=url_prefix)


        try:
            # 注册蓝图下的模型
            import_module(blueprint_path + ".models")
            # 注册蓝图下的后台站点配置
            import_module(blueprint_path+".admin")
        except:
            pass

把上面编写在users.urls中的admin站点配置代码,转义到users.admin中,并重新启动项目。

from application import admin,db
from .models import User
from flask_admin.contrib.sqla import ModelView

admin.add_view(ModelView(User, db.session))

2. 快速使用

2.1 修改默认首页

在蓝图初始化的辅助函数中通过配置进行默认首页重写内容主体模板.application.utils.__init__,代码:

from importlib import import_module
from flask import Blueprint

def path(rule,view_func):
    # 把蓝图下视图和路由之间的映射关系处理成字典结构,方便后面注册蓝图的时候,直接传参
    return {"rule":rule,"view_func":view_func}

def include(url_prefix, blueprint_path):
    """把路由前缀和蓝图进行关系映射"""
    return {"url_prefix":url_prefix,"blueprint_path":blueprint_path}

def api(name,method):
    """把api接口访问别名和视图进行关系映射"""
    return {"name":name, "method":method}

def init_blueprint(app):
    """自动注册蓝图"""
    # 读取蓝图列表
    blueprint_path_list = app.config.get("INSTALLED_APPS")
    # 读取总路由文件
    url_path = app.config.get("URL_PATH")
    urlpatterns = import_module(url_path).urlpatterns  # 加载蓝图下的子路由文件

    for blueprint_path in blueprint_path_list:
        blueprint_name = blueprint_path.split(".")[-1]
        # 自动创建蓝图对象
        blueprint = Blueprint(blueprint_name, blueprint_path)


        url_module = import_module("%s.urls" % blueprint_path)
        # 注册路由和视图
        try:
            for urls in url_module.urlpatterns:
                blueprint.add_url_rule(**urls)
        except:
            pass

        # 注册rpc接口
        try:
            for api in url_module.jsonpatterns:
                app.jsonrpc.site.register(blueprint_name.title()+"."+api["name"],api["method"])
        except:
            pass

        # 添加蓝图的路由前缀
        url_prefix = ""  # 蓝图路由前缀
        for urlpattern in urlpatterns:
            if urlpattern["blueprint_path"] == blueprint_name+".urls":
                url_prefix = urlpattern["url_prefix"]
                break

        # 注册蓝图对象到app应用对象中
        app.register_blueprint(blueprint, url_prefix=url_prefix)

        try:
            # 注册蓝图下的模型
            import_module(blueprint_path + ".models")
            # 注册蓝图下的后台站点配置
            import_module(blueprint_path+".admin")
        except:
            pass

        # 后台站点首页相关初始化
        from application import admin, AdminIndexView
        admin._set_admin_index_view(index_view=AdminIndexView(
            name=app.config["ADMIN_HOME_NAME"],
            template=app.config["ADMIN_HOME_TEMPLATE"],
        ))

在application下新增模板目录templates,并新增模板文件目录admin,并在admin目录下创建偶人首页的模板文件index.html,模板代码:

{% extends \'admin/master.html\' %}
{% block body %}
    <h1>admin站点默认首页</h1>
{% endblock %}

直接访问admin站点后台查看效果。

2.2 新增自定义导航

给admin站点新增用户导航,在application/templates下新增user模板目录,并创建admin/user/index.html模板文件,代码:

{% extends \'admin/master.html\' %}
{% block body %}
    <h1>用户自定义导航页面</h1>
    <p>{{title}}</p>
{% endblock %}

application/apps/users蓝图下,新增admin站点配置文件,把上面模板加载到admin导航中,代码:

from application import admin
from flask_admin import BaseView, expose
from flask import g

class AdminView(BaseView):
    @property
    def data(self):
        return {}

    """运营站点的基本视图类"""
    def render_template(self,template,**kwargs):
        # 收集当前作用域下所有的本地变量
        data = locals()

        data.pop("self")      # 移除当前对象
        data.pop("template")  # 移除当前模板变量
        return self.render(template=template, **data)

# 自定义一个导航页面
class UserAdmin(AdminView):
    """用户模型视图类"""
    @expose("/")
    def index(self,*args,**kwargs):
        self.data[\'title\'] = "admin站点用户相关的内容"
        return self.render_template(template="admin/user/index.html",**self.data)


admin.add_view(UserAdmin(name=\'用户\',url="user"))

把公共视图类的相关代码转到utils作为公共代码存在。utils/admin,代码:

from application import admin
from flask_admin import BaseView, expose

class AdminView(BaseView):
    @property
    def data(self):
        return {}

    """运营站点的基本视图类"""
    def render_template(self,template,**kwargs):
        # 收集当前作用域下所有的本地变量
        data = locals()

        data.pop("self")      # 移除当前对象
        data.pop("template")  # 移除当前模板变量
        return self.render(template=template, **data)

users/admin,代码:

from application.utils.admin import AdminView,expose,admin
# 自定义一个导航页面
class UserAdmin(AdminView):
    """用户模型视图类"""
    @expose("/")
    def index(self,*args,**kwargs):
        self.data[\'title\'] = "admin站点用户相关的内容"
        return self.render_template(template="admin/user/index.html",**self.data)

admin.add_view(UserAdmin(name=\'用户\',url="user"))

2.3 基于模型自动生成视图管理页面

application/apps/users/admin.py,代码:

from jinja2 import contextfunction

from application.utils.admin import AdminView,expose,admin
# 自定义一个导航页面
# class UserAdmin(AdminView):
#     """用户模型视图类"""
#     @expose("/")
#     def index(self,*args,**kwargs):
#         self.data[\'title\'] = "admin站点用户相关的内容"
#         return self.render_template(template="admin/user/index.html",**self.data)
#
# admin.add_view(UserAdmin(name=\'用户\',url="user"))

# 基于模型自动生成导航页面
from .models import User,db
from flask_admin.contrib.sqla import ModelView

class UserAdminModel(ModelView):
    # 列表页显示字段列表
    column_list = ["id","name","nickname","sex"]

    # 列表页显示排除字段列表
    # column_exclude_list = ["is_delete"]

    # 列表页可以直接编辑的字段列表
    column_editable_list = ["nickname","name"]

    # 是否允许查看详情
    can_view_details = True

    # 列表页显示直接可以搜索数据的字典
    column_searchable_list = [\'nickname\',\'name\', \'email\']

    # 过滤器
    column_filters = [\'sex\']

    # 单页显示数据量
    page_size = 10

    # 列表显示钩子
    def get_list(self, page, sort_field, sort_desc, search, filters, page_size=None):
        return super().get_list(page, sort_field, sort_desc, search, filters, page_size=None)

    def _get_list_value(self, context, model, name, column_formatters,
                        column_type_formatters):

        # 判断对应的字段,修改相应字段的显示
        if name=="sex":
            model.sex = "男" if model.sex else "女"

        return super()._get_list_value(context, model, name, column_formatters,
                        column_type_formatters)

    # 修改模型钩子
    def on_model_change(self,form, model, is_created):
        print(form)   # 客户端提交的表单数据
        print(model)  # 本次操作的数据数据
        print(is_created) # 本次操作是否属于添加操作,False表示修改

        return super().on_model_change(form, model, is_created)

    # 删除模型钩子
    def on_model_delete(self, model):
        # 删除日志的记录
        # 其他数据表是否存在外在关联
        return super().on_model_delete(model)

# 注册模型视图生成导航
# admin.add_view(UserAdminModel(User,db.session,name="用户"))

# 把当前页面添加到顶级导航下,category来设置,如果导航不存在,则自动创建
admin.add_view(UserAdminModel(User,db.session,name="用户信息", category="用户管理"))

# 添加子导航还有种方式: 添加超链接作为导航
from flask_admin.menu import MenuLink
admin.add_link(MenuLink(name=\'老男孩\', url=\'http://www.oldboyedu.com\', category=\'用户管理\')) # 把超链接作为子导航加载到顶级导航中

2.4 国际化与本地化

flask-babelex是Flask 的翻译扩展工具,在项目安装配置,可以实现中文显示。方便我们管理admin后台站点。

安装模块

pip install flask-babelex

模块初始化application/__init__.py,代码:

import os,sys,importlib

from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommand
from flask_jsonrpc import JSONRPC
from flask_marshmallow import Marshmallow
from flask_jwt_extended import JWTManager
from flask_admin import Admin
from flask_babelex import Babel

from application.utils import init_blueprint
from application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command

# 创建终端脚本管理对象
manager = Manager()

# 创建数据库链接对象
db = SQLAlchemy()

# redis链接对象
redis = FlaskRedis()

# Session存储对象
session_store = Session()

# 数据迁移实例对象
migrate = Migrate()

# 日志对象
log = Log()

# jsonrpc模块实例对象
jsonrpc = JSONRPC()

# 数据转换器的对象创建
ma = Marshmallow()

# jwt认证模块实例化
jwt = JWTManager()

# flask-admin模块初始化
admin = Admin()

babel = Babel()

def init_app(config_path):
    """全局初始化"""
    # 创建app应用对象
    app = Flask(__name__)
    # 项目根目录
    app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    # 加载导包路径
    sys.path.insert(0, os.path.join(app.BASE_DIR,"application/utils/language"))

    # 加载配置
    Config = load_config(config_path)
    app.config.from_object(Config)

    # 数据库初始化
    db.init_app(app)
    redis.init_app(app)

    # 数据转换器的初始化
    ma.init_app(app)

    # session存储初始化
    init_session(app)
    session_store.init_app(app)

    # 数据迁移初始化
    migrate.init_app(app,db)
    # 添加数据迁移的命令到终端脚本工具中
    manager.add_command(\'db\', MigrateCommand)

    # 日志初始化
    app.log = log.init_app(app)

    # 蓝图注册
    init_blueprint(app)

    # jsonrpc初始化
    jsonrpc.service_url = "/api" # api接口的url地址前缀
    jsonrpc.init_app(app)

    # jwt初始化
    jwt.init_app(app)

    # 初始化终端脚本工具
    manager.app = app

    # 注册自定义命令
    load_command(manager)

    # admin站点
    from flask_admin import AdminIndexView
    admin.init_app(app)
    
    # 项目语言
    babel.init_app(app)

    return manager

语言配置,application/settings/__init__.py,代码:

    # 国际化与本地化
    LANGUAGE = "zh_CN"
    TIMEZONE = "Asia/Shanghai"

    # 针对babel模块的语言和设置
    BABEL_DEFAULT_LOCALE = LANGUAGE
    BABEL_DEFAULT_TIMEZONE = TIMEZONE

3. 基于Faker生成仿真测试数据

文档:https://faker.readthedocs.io/en/master/

安装

pip install Faker

初始化,application/__init__.py, 因此接下来需要自定义终端命令,所以设置db对象和faker对象作为app应用对象的子对象存在,方便引入使用,代码:

import os,sys

from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_redis import FlaskRedis
from flask_session import Session
from flask_migrate import Migrate,MigrateCommand
from flask_jsonrpc import JSONRPC
from flask_marshmallow import Marshmallow
from flask_jwt_extended import JWTManager
from flask_admin import Admin
from flask_babelex import Babel
from faker import Faker

from application.utils import init_blueprint
from application.utils.config import load_config
from application.utils.session import init_session
from application.utils.logger import Log
from application.utils.commands import load_command

# 创建终端脚本管理对象
manager = Manager()

# 创建数据库链接对象
db = SQLAlchemy()

# redis链接对象
redis = FlaskRedis()

# Session存储对象
session_store = Session()

# 数据迁移实例对象
migrate = Migrate()

# 日志对象
log = Log()

# jsonrpc模块实例对象
jsonrpc = JSONRPC()

# 数据转换器的对象创建
ma = Marshmallow()

# jwt认证模块实例化
jwt = JWTManager()

# flask-admin模块实例化
admin = Admin()

# flask-babelex模块实例化
babel = Babel()


def init_app(config_path):
    """全局初始化"""
    # 创建app应用对象
    app = Flask(__name__)
    # 项目根目录
    app.BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    # 加载导包路径
    sys.path.insert(0, os.path.join(app.BASE_DIR,"application/utils/language"))

    # 加载配置
    Config = load_config(config_path)
    app.config.from_object(Config)

    # 数据库初始化
    db.init_app(app)
    app.db = db
    redis.init_app(app)

    # 数据转换器的初始化
    ma.init_app(app)

    # session存储初始化
    init_session(app)
    session_store.init_app(app)

    # 数据迁移初始化
    migrate.init_app(app,db)
    # 添加数据迁移的命令到终端脚本工具中
    manager.add_command(\'db\', MigrateCommand)

    # 日志初始化
    app.log = log.init_app(app)

    # 蓝图注册
    init_blueprint(app)

    # jsonrpc初始化
    jsonrpc.service_url = "/api" # api接口的url地址前缀
    jsonrpc.init_app(app)

    # jwt初始化
    jwt.init_app(app)

    # admin初始化
    admin.init_app(app)

    # 国际化本地化模块的初始化
    babel.init_app(app)

    # 初始化终端脚本工具
    manager.app = app

    # 数据种子生成器[faker]
    app.faker = Faker(app.config.get("LANGUAGE"))

    # 注册自定义命令
    load_command(manager)

    return manager

基本使用,代码

# 随机IP地址
from faker import Faker
from faker.providers import internet

fake = Faker()
fake.add_provider(internet)

print(fake.ipv4_private())

# 产生随机手机号
print(fake.phone_number())
# 产生随机姓名
print(fake.name())
# 产生随机地址
print(fake.address())
# 随机产生国家名
print(fake.country())
# 随机产生国家代码
print(fake.country_code())
# 随机产生城市名
print(fake.city_name())
# 随机产生城市
print(fake.city())
# 随机产生省份
print(fake.province())
# 产生随机email
print(fake.email())
# 产生随机IPV4地址
print(fake.ipv4())
# 产生长度在最大值与最小值之间的随机字符串
print(faker.pystr(min_chars=0, max_chars=8))

# 随机产生车牌号
print(fake.license_plate())

# 随机产生颜色
print(fake.rgb_color())  # rgb
print(fake.safe_hex_color())  # 16进制
print(fake.color_name())  # 颜色名字
print(fake.hex_color()) # 16进制

# 随机产生公司名
print(fake.company())

# 随机产生工作岗位
print(fake.job())
# 随机生成密码
print(fake.password(length=10, special_chars=True, digits=True, upper_case=True, lower_case=True))
# 随机生成uuid
print(fake.uuid4())
# 随机生成sha1
print(fake.sha1(raw_output=False))
# 随机生成md5
print(fake.md5(raw_output=False))

# 随机生成女性名字
print(fake.name_female())
# 男性名字
print(fake.name_male())
# 随机生成名字
print(fake.name())

# 生成基本信息
print(fake.profile(fields=None, sex=None))
print(fake.simple_profile(sex=None))

# 随机生成浏览器头user_agent
print(fake.user_agent())

# 随机产生时间 月份
print(fake.month_name())
# \'May\'
print(fake.date_time_this_century(before_now=True, after_now=False, tzinfo=None))
# 207-09-18 12:21:32
print(fake.time_object(end_datetime=None))
# 16:51:21
print(fake.date_time_between(start_date="-10y", end_date="now", tzinfo=None))
# 2015-11-15 21:07:38
print(fake.future_date(end_date="+30d", tzinfo=None))
# 2020-04-25
print(fake.date_time(tzinfo=None, end_datetime=None))
# 2002-09-01 18:27:45
print(fake.date(pattern="%Y-%m-%d", end_datetime=None))
# \'1998-08-02\'
print(fake.date_time_this_month(before_now=True, after_now=False, tzinfo=None))
# 2020-04-03 16:03:21
print(fake.date_time_this_decade(before_now=True, after_now=False, tzinfo=None))
# 2020-01-09 01:15:08
print(fake.month())
# \'11\'
print(fake.day_of_week())
# \'Sunday\'
print(fake.date_object(end_datetime=None))
# 2017-06-26
print(fake.date_this_decade(before_today=True, after_today=False))
# 2020-03-30
fake.date_this_century(before_today=True, after_today=False)
# datetime.date(2000, 6, 1)
fake.date_this_month(before_today=True, after_today=False)
# datetime.date(2018, 6, 13)
fake.past_datetime(start_date="-30d", tzinfo=None)
# datetime.datetime(2018, 6, 25, 7, 41, 34)
fake.date_this_year(before_today=True, after_today=False)
# datetime.date(2018, 2, 24)
fake.date_time_between_dates(datetime_start=None, datetime_end=None, tzinfo=None)
# datetime.datetime(2018, 6, 26, 14, 40, 5)
fake.date_time_ad(tzinfo=None, end_datetime=None)
# datetime.datetime(673, 1, 28, 18, 17, 55)
fake.date_between_dates(date_start=None, date_end=None)
# datetime.date(2018, 6, 26)
fake.future_datetime(end_date="+30d", tzinfo=None)
# datetime.datetime(2018, 7, 4, 10, 53, 6)
fake.past_date(start_date="-30d", tzinfo=None)
# datetime.date(2018, 5, 30)
fake.time(pattern="%H:%M:%S", end_datetime=None)
# \'01:32:14\'
fake.day_of_month()
# \'19\'
fake.unix_time(end_datetime=None, start_datetime=None)

fake.date_time_this_year(before_now=True, after_now=False, tzinfo=None)
# datetime.datetime(2018, 5, 24, 11, 25, 25)
fake.date_between(start_date="-30y", end_date="today")
# datetime.date(2003, 1, 11)
fake.year()
# \'1993\'

自定义终端命令,生成指定数量的测试用户,代码:

import os,inspect,random
from flask_script import Command, Option
from importlib import import_module
from flask import current_app
from faker.providers import internet

def load_command(manager,command_path=None):
    """自动加载自定义终端命令"""
    if command_path is None:
        command_path = manager.app.config["COMMAND_PATH"]

    module = import_module(command_path)
    class_list = inspect.getmembers(module, inspect.isclass)
    for class_item in class_list:
        if issubclass(class_item[1],Command) and class_item[0] != "Command":
            manager.add_command(class_item[1].name,class_item[1])

class BlueprintCommand(Command):
    """生成蓝图的终端命令"""

    # 终端调用别名
    name = "blue" # python manage.py blue

    # 参数列表
    option_list = [
        Option(\'--name\', \'-n\', dest=\'name\'),
    ]

    def run(self, name):
        # 生成蓝图名称对象的目录
        os.mkdir(name)
        open("%s/__init__.py" % name, "w")
        open("%s/views.py" % name, "w")
        open("%s/models.py" % name, "w")
        with open("%s/urls.py" % name, "w") as f:
            content = """from . import views
from application.utils import path
urlpatterns = [

]"""
            f.write(content)
        print("蓝图%s创建完成...." % name)

class FakerCommand(Command):
    """生成测试的工具类"""
    name = "faker"
    option_list = [
        Option(\'--type\', \'-t\', dest=\'type\',default="user"), # 生成数据的类型
        Option(\'--num\', \'-n\', dest=\'num\',default=1),   # 生成数据的数量
    ]

    type_list = [
        "user"
    ]

    def run(self, type, num):
        if type not in self.type_list:
            print("数据类型不正确\\n当前Faker生成数据类型仅支持: %s" % self.type_list)
            return None
        num = int(num)
        if num < 1:
            print("生成数量不正确\\n当前Faker生成数据至少1个以上")
            return None

        if type == "user":
            self.create_user(num)

    def create_user(self,num):
        """生成指定数量的测试用户信息"""
        with current_app.app_context():
            from application.apps.users.models import User, UserProfile,db
            faker = current_app.faker
            faker.add_provider(internet)

        user_list = []
        password = "123456"
        for _ in range(0, num):
            sex = bool(random.randint(0, 2))
            if sex:
                # 男生
                nickname = faker.name_male()
            else:
                nickname = faker.name_female()

            # 登录账号[随机字母,6-16位]
            name = faker.pystr(min_chars=6, max_chars=16)

            # 生成指定范围的时间对象
            age = random.randint(13, 50)
            birthday = faker.date_time_between(start_date="-%sy" % age, end_date="-12y", tzinfo=None)

            hometown_province = faker.province()
            hometown_city = faker.city()
            hometown_area = faker.district()

            living_province = faker.province()
            living_city = faker.city()
            living_area = faker.district()

            user = User(
                nickname=nickname,
                sex=sex,
                name=name,
                age=age,
                password=password,
                money=random.randint(100, 99999),
                ip_address=faker.ipv4_public(),
                email=faker.ascii_free_email(),
                mobile=faker.phone_number(),
                unique_id=faker.uuid4(),
                province=faker.province(),
                city=faker.city(),
                area=faker.district(),
                info=UserProfile(
                    birthday=birthday,
                    hometown_province=hometown_province,
                    hometown_city=hometown_city,
                    hometown_area=hometown_area,
                    hometown_address=hometown_province + hometown_city + hometown_area + faker.street_address(),
                    living_province=living_province,
                    living_city=living_city,
                    living_area=living_area,
                    living_address=living_province + living_city + living_area + faker.street_address()
                )
            )

            user_list.append(user)

        db.session.add_all(user_list)
        db.session.commit()

        print("生成%s个用户信息完成..." % num)

清理下原来的垃圾数据,打开数据库终端

# 关闭外键检查
SET FOREIGN_KEY_CHECKS = 0;
truncate table mf_user;
truncate table mf_user_profile;
# 重启外键检查
SET FOREIGN_KEY_CHECKS = 1;

以上是关于flask- admin的主要内容,如果未能解决你的问题,请参考以下文章

flask_admin 笔记二 授权和权限

Wordpress阻止访问wp admin€“wpsnipp.com网站你博客的Wordpress代码片段

Flask-Admin Bootstrap 4 X-editable date 导致错误

Flask-admin

flask-admin有用的例子

Flask初识