Flask扩展包之flask-admin

入门


初始化

第一步是为Flask应用初始化一个空的管理界面:

from flask import Flask
from flask_admin import Admin

app = Flask(__name__)

admin = Admin(app, name='microblog', template_mode='bootstrap3')
# Add administrative views here

app.run()

这里,nametemplate_mode参数都是可选的。或者,您可以使用该init_app()方法。

如果您启动此应用程序并导航到http:// localhost:5000 / admin /,您应该会在顶部看到一个带有导航栏的空白页面。

添加模型视图

模型视图允许您添加一组专用管理页面,用于管理数据库中的任何模型。通过创建ModelView类的实例来执行此操作,您可以从Flask-Admin的内置ORM后端之一导入该类。一个例子是SQLAlchemy后端,您可以按如下方式使用它:

from flask_admin.contrib.sqla import ModelView

# Flask and Flask-SQLAlchemy initialization here

admin = Admin(app, name='microblog', template_mode='bootstrap3')
admin.add_view(ModelView(User, db.session))
admin.add_view(ModelView(Post, db.session))

开箱即用,这为您的模型提供了一组功能齐全的CRUD视图:

  • 一个列表视图,用于搜索,排序,过滤和删除记录的支持。
  • 一个创建视图添加新记录。
  • 用于更新现有记录编辑视图。
  • 可选的只读详细信息视图。

有许多选项可用于自定义这些内置视图的显示和功能。有关详细信息,请参阅自定义内置视图有关可用的其他ORM后端的更多详细信息,请参阅使用不同的数据库后端

向索引页面添加内容

当你访问http:// localhost:5000 / admin /时,你会注意到的第一件事 是它只是一个带有导航菜单的空白页面。要向此页面添加一些内容,请在项目的templates目录中将以下文本另存为admin / index.html

{% extends 'admin/master.html' %}

{% block body %}
  <p>Hello world</p>
{% endblock %}

这将覆盖默认索引模板,但仍会为您提供内置导航菜单。因此,现在您可以将任何内容添加到索引页面,同时保持一致的用户体验。

授权和权限


为应用程序设置管理界面时,您要解决的首要问题之一是如何阻止不需要的用户。使用Flask-Admin,有几种不同的方法可以解决这个问题。

HTTP 

不幸的是,没有简单的方法可以将HTTP Basic Auth应用到您的管理界面。

最简单的身份验证形式是HTTP Basic Auth。它不会干扰您的数据库模型,也不需要您编写任何新的视图逻辑或模板代码。因此,在您希望全世界都能看到它之前,部署仍处于开发阶段的内容时,这非常棒。

看看Flask-BasicAuth,看看将整个应用程序置于HTTP Basic Auth之后是多么容易。

滚动你自己

对于更灵活的解决方案,Flask-Admin允许您通过简单地覆盖is_accessible方法来定义每个管理视图类的访问控制规则您如何实现逻辑取决于您,但如果您使用像Flask-Login这样的低级库 ,则限制访问可能非常简单:

class MicroBlogModelView(sqla.ModelView):

    def is_accessible(self):
        return login.current_user.is_authenticated

    def inaccessible_callback(self, name, **kwargs):
        # redirect to login page if user doesn't have access
        return redirect(url_for('login', next=request.url))

在导航菜单中,不会为该用户显示特定用户无法访问的组件。有关在Flask-Admin中使用Flask-Login的示例,请查看https://github.com/flask-admin/Flask-Admin/tree/master/examples/auth-flask-login

主要缺点是您仍需要自己实现所有相关的登录,注册和帐户管理视图。

使用烧瓶安全

如果您想要更精细的解决方案,可以使用Flask-Security,这是一个更高级别的库。它提供了许多内置视图,用于执行用户注册,登录,电子邮件地址确认,密码重置等常见操作。

唯一复杂的一点是使内置的Flask-Security视图与Flask-Admin模板顺利集成,以创建一致的用户体验。为此,您需要覆盖内置的Flask-Security模板,并通过在每个文件的顶部添加以下内容来扩展Flask-Admin基本模板:

{% extends 'admin/master.html' %}

现在,您需要手动传入Flask-Admin模板的一些上下文变量,以便在从Flask-Security视图中调用它们时正确呈现。定义security_context_processor函数将为您解决此问题:

def security_context_processor():
    return dict(
        admin_base_template=admin.base_template,
        admin_view=admin.index_view,
        h=admin_helpers,
    )

有关在Flask-Admin中使用Flask-Security的工作示例,请查看 https://github.com/flask-admin/Flask-Admin/tree/master/examples/auth

该示例仅使用内置寄存器登录视图,但您可以按照相同的方法来包含其他视图,例如forgot_passwordsend_confirmation等。

自定义内置视图


内置的ModelView类非常适合快速入门。但是,您需要配置其功能以适合您的特定型号。这是通过设置ModelView类中可用的配置属性的值来完成的

要指定一些全局配置参数,可以将ModelView子类化,并在将模型添加到接口时使用该子类:

from flask_admin.contrib.sqla import ModelView

# Flask and Flask-SQLAlchemy initialization here

class MicroBlogModelView(ModelView):
    can_delete = False  # disable model deletion
    page_size = 50  # the number of entries to display on the list view

admin.add_view(MicroBlogModelView(User, db.session))
admin.add_view(MicroBlogModelView(Post, db.session))

或者,以同样的方式,您可以一次为单个模型指定选项:

class UserView(ModelView):
        can_delete = False  # disable model deletion

class PostView(ModelView):
        page_size = 50  # the number of entries to display on the list view

admin.add_view(UserView(User, db.session))
admin.add_view(PostView(Post, db.session))

ModelView配置属性

有关已定义属性的完整列表,请查看API文档BaseModelView()以下是一些最常用的属性:

禁用某些CRUD操作,请设置以下任何布尔参数:

can_create = False
can_edit = False
can_delete = False

如果模型中有太多数据要显示在列表视图中,则可以通过设置添加只读详细信息视图

can_view_details = True

从列表视图中删除列很简单,只需传递column_excludes_list参数的列名列表

column_exclude_list = ['password', ]

为了使搜索栏,或将其用于过滤,指定列名的列表:

column_searchable_list = ['name', 'email']
column_filters = ['country']

要获得更快的编辑体验,请在列表视图中启用内联编辑

column_editable_list = ['name', 'last_name']

或者,在列表页面模态窗口中显示添加和编辑表单,而不是专用的创建编辑页面:

create_modal = True
edit_modal = True

您可以通过指定选择选项列表来限制文本字段的可能值

form_choices = {
    'title': [
        ('MR', 'Mr'),
        ('MRS', 'Mrs'),
        ('MS', 'Ms'),
        ('DR', 'Dr'),
        ('PROF', 'Prof.')
    ]
}

要从创建和编辑表单中删除字段

form_excluded_columns = ['last_name', 'email']

要指定WTForms字段参数

form_args = {
    'name': {
        'label': 'First Name',
        'validators': [required()]
    }
}

或者,指定用于呈现这些字段WTForms小部件的参数

form_widget_args = {
    'description': {
        'rows': 10,
        'style': 'color: black'
    }
}

当您的表单包含外键时,请通过ajax加载这些相关模型,使用:

form_ajax_refs = {
    'user': {
        'fields': ['first_name', 'last_name', 'email'],
        'page_size': 10
    }
}

要过滤通过ajax加载的结果,您可以使用:

form_ajax_refs = {
    'active_user': QueryAjaxModelLoader('user', db.session, User,
                                 filters=["is_active=True", "id>1000"])
}

内联管理相关模型

inline_models = ['post', ]

这些内联表单可以自定义。查看API文档 inline_models()

启用模型视图的csv导出

can_export = True

这将向模型视图添加一个按钮,用于导出记录,截断为export_max_rows

添加自己的视图


对于您的要求非常具体并且您很难通过内置ModelView来满足它们的情况,Flask-Admin使您可以轻松地完全控制并将自己的视图添加到界面中。

独立视图

可以通过扩展BaseView类并定义自己的视图方法来添加一组独立视图(不依赖于任何特定模型) 例如,要添加显示来自第三方API的某些分析数据的页面:

from flask_admin import BaseView, expose

class AnalyticsView(BaseView):
    @expose('/')
    def index(self):
        return self.render('analytics_index.html')

admin.add_view(AnalyticsView(name='Analytics', endpoint='analytics'))

这将为您的视图添加指向导航栏的链接。请注意,它以“/”(根URL)提供。这是对独立视图的限制:至少每个视图类至少需要一个方法来在其根目录下提供视图。

上面示例analytics_index.html模板可能如下所示:

{% extends 'admin/master.html' %}
{% block body %}
  <p>Here I'm going to display some data.</p>
{% endblock %}

通过扩展admin / master.html模板,您可以保持一致的用户体验,即使在严格控制页面内容的同时也是如此。

覆盖内置视图

在某些情况下,您可能需要大多数内置的ModelView功能,但您希望替换默认的创建编辑列表视图之一。为此,您只能覆盖有问题的视图,并且它的所有链接仍将按预期运行:

from flask_admin.contrib.sqla import ModelView

# Flask and Flask-SQLAlchemy initialization here

class UserView(ModelView):
    @expose('/new/', methods=('GET', 'POST'))
    def create_view(self):
    """
        Custom create view.
    """

    return self.render('create_user.html')

使用内置模板


Flask-Admin使用Jinja2模板引擎。

扩展内置模板

而不是完全覆盖内置模板,最好扩展它们。这将使您以后升级到新的Flask-Admin版本变得更加简单。

在内部,Flask-Admin模板派生自admin / master.html模板。您可以扩展的三个最有趣的模板:

  • 管理/模型/ list.html
  • 管理/模型/ create.html上
  • 管理/模型/ edit.html

使用您自己的功能扩展默认编辑模板,请在templates / microblog_edit.html中创建一个模板, 如下所示:

{% extends 'admin/model/edit.html' %}

{% block body %}
    <h1>MicroBlog Edit View</h1>
    {{ super() }}
{% endblock %}

现在,要使您的视图类使用此模板,请设置适当的类属性:

class MicroBlogModelView(ModelView):
    edit_template = 'microblog_edit.html'
    # create_template = 'microblog_create.html'
    # list_template = 'microblog_list.html'

如果要使用自己的基本模板,请在初始化期间将模板名称传递给admin构造函数:

admin = Admin(app, base_template='microblog_master.html')

覆盖内置模板

要完全控制管理界面的样式和布局,您可以覆盖所有内置模板。请记住,模板会从一个版本的Flask-Admin略微改变到下一个版本,所以一旦你开始覆盖它们,你需要在升级包版本时要小心。

要覆盖任何内置模板,只需将它们从Flask-Admin源复制到项目的templates / admin /目录中。只要文件名保持不变,项目目录中的模板应自动优先于内置模板。

可用的模板块

Flask-Admin admin / master.html定义了一个基本模板,其中包含所有其他管理模板。此模板是指向admin / base.html的代理,它定义了以下块:

阻止名称描述
head_meta 标题中的页面元数据
标题 页面标题
head_css 标题中包含各种CSS
HTML头中的空块,以防你想在那里放东西
page_body 页面布局
菜单栏中的徽标
主菜单 主菜单
menu_links 链接菜单
访问控制 菜单右侧的部分(可用于添加登录/注销按钮)
消息 提醒和各种消息
身体 内容(显示视图的位置)
尾巴 内容空白区域

除了从admin / master.html继承的所有块之外admin / model / list.html模板还包含以下块:

阻止名称描述
model_menu_bar 菜单栏
model_list_table 表容器
list_header 表头行
list_row_actions_header 动作标题
list_row 单排
list_row_actions 带有编辑/删除/等按钮的行动单元格
empty_list_message 如果找不到模型,将显示的消息

请查看https://github.com/flask-admin/flask-admin/tree/master/examples/layout上的布局示例, 了解如何对管理界面进行完整的风格控制。

环境变量

在扩展admin / master.html的任何模板中工作时,您可以访问少量环境变量:

变量名描述
admin_view 当前的管理视图
admin_base_template 基本模板名称
_gettext Babel gettext
_ngettext Babel ngettext
H 来自helpers模块的助手

生成

要生成特定视图的URL,请使用带有点前缀的url_for

from flask import url_for

class MyView(BaseView):
    @expose('/')
    def index(self):
        # Get URL for the test view method
        user_list_url = url_for('user.index_view')
        return self.render('index.html', user_list_url=user_list_url)

还可以引用特定记录:

# Edit View for record #1 (redirect back to index_view)
url_for('user.edit_view', id=1, url=url_for('user.index_view'))

引用ModelView实例时,在调用url_for时使用模型的小写名称作为前缀可以通过为每个视图指定唯一端点并将其用作前缀来引用其他视图。所以,你可以使用:

url_for('analytics.index')

如果您的视图端点定义如下:

admin.add_view(CustomView(name='Analytics', endpoint='analytics'))

 

 

 

posted @ 2018-11-26 11:44  #随风飘散  阅读(6410)  评论(0编辑  收藏  举报