2016-11-02 23 views
0

我正在使用flask_admin來允許管理員用戶訪問數據庫,其中提供了一對多關係。編輯條目時,我希望下拉菜單隻顯示符合條件的選項。我雖然query_factory可以做到這一點。以下是我現在有小例子:如何自定義瓶子管理QuerySelectMultipleField的選擇?

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。這似乎是一個簡單的任務,但我找不到辦法。或者,也許這種方法是不可行的?

回答

1

經過數小時的嘗試/錯誤和谷歌搜索,似乎this幾乎是我想要做的。問題歸結爲當ModelView啓動時edit_form不會被調用。因此我相信沒有直接的方式來訪問正在編輯的模型實例。解決方法是覆蓋edit_form並在模型實例正在傳遞的地方創建obj變量。這是我工作的代碼(基於最小化的例子)

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) 
     )