2

这是关于 Flask-appbuilder 的一个非常具体的问题。在我的开发过程中,我发现 FAB 的 ModelView 适合管理员角色,但需要更多的用户逻辑处理程序/视图来进行复杂的设计。

设备用户之间存在多对多的关系,因为每个设备可以在多个用户之间共享,每个用户可以拥有多个设备。于是就有了一张叫做accesses的二级表,描述了设备用户之间的访问控制。在此表中,如果用户拥有该设备,我将添加“isHost”。因此,我们有两个角色:主机和(普通)用户。但是,这些角色不是定义为其他应用程序的两个角色,因为一个人可以同时是主机或用户。在一个非常简单的应用程序中,强制用户切换两个角色不是很方便。这让事情变得更糟。

无论如何,我需要使用传统的 Flask/Jinja2 模板设计一些自定义处理程序。例如:

class PageView(ModelView):
    # FAB default URL: "/pageview/list"
    datamodel = SQLAInterface(Page)
    list_columns = ['name', 'date', 'get_url']

    @expose("/p/<string:url>")
    def p(self, url):
        title = urllib.unquote(url)
        r = db.session.query(Page).filter_by(name = title).first()

        if r:
            md = r.markdown
            parser = mistune.Markdown()
            body = parser(md)
            return self.render_template('page.html', title = title, body = body)
        else:
            return self.render_template('404.html'), 404

上面的降价页面 URL 很简单,因为它是一个单独的 UI。但是如果我去 DeviceView/AccountView/AccessView 进行列表/显示/添加/编辑操作。我意识到我需要一个独特风格的 UI。

那么,现在如何通过自定义 sqlalchemy 查询重用 FAB 的现有模板/小部件?这是我的 DeviceView 代码。

class DeviceView(ModelView):
    datamodel = SQLAInterface(Device)
    related_views = [EventView, AccessView]

    show_template = 'appbuilder/general/model/show_cascade.html'
    edit_template = 'appbuilder/general/model/edit_cascade.html'

    @expose('/host')
    @has_access
    def host(self):
        base_filters = [['name', FilterStartsWith, 'S'],]
        #if there is not return, FAB will throw error
        return "host view:{}".format(repr(base_filters))

    @expose('/my')
    @has_access
    def my(self):
        # A pure testing method
        rec = db.session.query(Access).filter_by(id = 1).all()      
        if rec:
            for r in rec:
                print "rec, acc:{}, dev:{}, host:{}".format(r.account_id, r.device_id, r.is_host)
            return self.render_template('list.html', title = "My Accesses", body = "{}".format(repr(r)))
        else:
            return repr(None)

除了带有 render_template() 的 sqlalchemy 代码,我猜 base_filters 还可以帮助定义自定义查询,但是,我不知道如何获取查询结果并渲染它们。

如果可能,请给我一些参考代码或示例。实际上,我在 FAB 的 github 资源中有 grep 关键字“db.session/render_template/expoaw”。但没有运气。

4

0 回答 0