Alex
Alex

Reputation: 95

Flask-admin editable select column row-based filter

I am using flask-admin to have easy edits on my DB model. It is about renting out ski to customers.

This is my rental view (the sql_alchemy DB model is accordingly):

class RentalView(ModelView):
    column_list = ("customer", "from_date", "to_date", "ski", "remarks")
    ...

customer and ski are relationship fields to the respective model. I want to only show these ski in the edit view that are not rented by others in this time period.

I have been searching everywhere how to dynamically set the choices of the edit form but it simply does not work fully.

I tried doing

def on_form_prefill(self, form, id):
    query = db.session.query... # do the query based on the rental "id"
    form.ski.query = query

and this correctly shows the filtered queries. However, when submitting the form, the .query attribute of the QuerySelectField ski is None again, hence leading to a query = self.query or self.query_factory() TypeError: 'NoneType' object is not callable error. No idea why the query is being reset?!

Does anybody know a different strategy of how to handle dynamic queries, based on the edited object's id?

Upvotes: 1

Views: 877

Answers (1)

pjcunningham
pjcunningham

Reputation: 8046

Use this pattern, override the view's edit_form method, instance the default edit form (by calling the super() method then modify the form as you wish:

class RentalView(ModelView):

    # setup edit forms so that Ski relationship is filtered
    def edit_form(self, obj):

        # obj is the rental instance being edited
        _edit_form = super(RentalView, self).edit_form(obj)

        # setup your dynamic query here based on obj.id
        # for example

        _edit_form.ski.query_factory = lambda: Ski.query.filter(Ski.rental_id == obj.id).all()

        return _edit_form

Upvotes: 1

Related Questions