How to handle ordered many-to-many relationship (association proxy) in Flask-Admin form?

前端 未结 2 1545
星月不相逢
星月不相逢 2021-02-09 16:10

I have a many-to-many relationship between declarative models Page and Survey, which is mediated by association proxies because the order in wh

2条回答
  •  猫巷女王i
    2021-02-09 17:05

    This answer related to Dynamic filter on foreignkey in flask-admin, which I think is a very common situation when you would like selection list of field B depends on value of field A etc.

    This link might contains helpful information also: https://github.com/flask-admin/flask-admin/issues/797

    I have found a solution to this by using on_form_prefill together with query_factory, here are the steps

    In the admin definition, override the default implementation of on_form_prefill, and in that method, you can get the current object being edited, so you can define the query_factory of another field based on the current defined field, code shown below:

    class ReceivingAdmin(ModelView):
            def on_form_prefill(self, form, id):
    
            # Get field(purchase_order_id) from the current object being edited via form._obj.purchase_order_id
            if form is not None and form._obj is not None and form._obj.purchase_order_id is not None:
                po_id = form._obj.purchase_order_id
                # Define a dynamic query factory based on current data.
                # Please notice since the po_id parameter need to be passed to the function,
                # So functools.partial is used
                form.lines.form.purchase_order_line.kwargs['query_factory'] =\
                    partial(PurchaseOrderLine.header_filter, po_id)
    

    And here is the definition of the query factory in the model:

    class PurchaseOrderLine(db.Model):
        @staticmethod
        def header_filter(po_id):
            return AppInfo.get_db().session.query(PurchaseOrderLine).filter_by(purchase_order_id=po_id)
    

    By this way, we could control which record will be shown in the purchase order line list based on parameter po_id, and the value of po_id is passed to the query factory function in on_form_prefill.

提交回复
热议问题