如何自定义烧瓶管理员QuerySelectMultipleField选择? [英] How to customize flask admin QuerySelectMultipleField choice?

查看:240
本文介绍了如何自定义烧瓶管理员QuerySelectMultipleField选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用flask_admin允许管理员用户访问存在一对多关系的数据库.编辑条目时,我希望下拉菜单仅显示符合条件的选项.我虽然query_factory可以做到这一点.以下是我现在拥有的最小示例:

I am using flask_admin to allow admin user to access database, where one-to-many relationship is presented. When editing an entry, I would like the dropdown menu to show only the options that meet the condition. I though query_factory can do this. The following is minimal example of what I have now:

class OneSideObj(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    active = db.Column(db.Boolean)
    many_side_obj_id = db.Column(
        db.Integer,
        db.ForeignKey('many_side_obj.id')
    )

class ManySideObj(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    one_side_objs = db.relationship(
        'OneSideObj',
        backref = 'many_side_obj',
        lazy = 'dynamic',
    )

def get_manysideobj_id(*args):
    ##################
    # how to get id? #
    ##################
    return id

class ManySideObjView(ModelView):
    id = get_manysideobj_id(*some_args) # <--- get current many_side_obj id

    form_args = {
        'one_side_objs': {
            'query_factory': lambda: query_filter(id)
        }
    }

def query_filter(id):
    return OneSideObj.query.filter(
        (OneSideObj.many_side_obj_id == id) | (OneSideObj.active == False)
    )

我希望该字段显示的查询都是非活动的OneSideObj或活动的,但具有匹配的many_side_obj_id.我对获取当前模型实例ID感到困惑.这似乎是一个简单的任务,但我找不到解决方法.还是这种方法不可行?

The query I would like the field to display is all inactive OneSideObj, or active ones but with the matching many_side_obj_id. I am stuck with by getting current model instance ID. It seems to be a simple task but I can't find the way to do it. Or maybe this approach is not doable?

推荐答案

经过数小时的尝试/错误和谷歌搜索,看来

After hours of try/error and googling, it seems this is almost what I want to do. The problem boils down to the fact that edit_form will not be called when ModelView initiated. Therefore I believe there is no direct way to access the model instance that is being edited. The work around is to overwrite edit_form and hijact the obj variable where the model instance is being passed. This is the code working for me (based on the minimized example)

class ManySideObjView(ModelView):

    # model instance is passed to edit_form as obj
    def edit_form(self, obj):
        return self._filtered(
            super(ManySideObjView, self).edit_form(obj), obj.id
        )

    # save id in self._instance_id and access it from _get_list
    def _filtered(self, form, id):
        self._instance_id = id
        form.one_side_objs.query_factory = self._get_list
        return form

    # actual query logic
    def _get_list(self):
        id = self._instance_id

        return self.session.query(OneSideObj).filter(
            (OneSideObj.active == False) | (OneSideObj.many_side_obj_id == id)
        )

这篇关于如何自定义烧瓶管理员QuerySelectMultipleField选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆