Search code examples
python-3.xflaskflask-admin

How to access model field value before edit form presented to user in flask-admin?


I have model User:

 class User(db.Model):

    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    token_life_time = db.Column(db.Integer, nullable=False)

and ModelView for it from flask-admin:

class UserModelView(ModelView):

    column_list = ('id', 'username', 'token_life_time')
    form_create_rules = ('username', 'token_life_span') # custom field, that doesn't exist in actual model
    form_edit_rules = ('username', 'token_life_time', 'new_token_life_time')
    form_extra_fields = {
        'token_life_span': StringField(default='1-0-0-0', validators=[DataRequired()]),
        'new_token_life_time': StringField() # how to put here actual value from model.token_life_time as default value in EDIT form ???
    }

    column_formatters = dict(
        token_life_time=lambda v, c, m, p: UserModelView.convert_seconds_to_human_readable(m.token_life_time)
    )
    
    def on_model_change(self, form, model, is_created):
        token_time = form.data.get('token_life_span', None)
        if token_time:
            model.token_life_time = self.convert_to_seconds(token_time) # my custom function  that converts string of format (days-hours-minutes-seconds, example: 1-8-23-15) into seconds for storing in DB int type

I want to access model.token_life_time value before EDIT form presented to user and convert it from seconds to human readable string (with days, hours etc.). Then to put converted value as default value in custom field in edit form (new_token_life_time).

The question is - how to access actual value from model and then put converted value to custom field as default value in EDIT form ???


Solution

  • Override the view's edit_form method - see documentation.

    Something like the following:

    class UserModelView(ModelView):
    
        def edit_form(self, obj=None):
            form = super().edit_form(obj=obj)
            # calculate token_life_span
            _token_life_span = get_token_life_span(obj.token_life_time)
            form.token_life_span.data = _token_life_span
            return form