Luca Brozzi
Luca Brozzi

Reputation: 335

How override Flask-Admin's edit_form() maintaining previous values as placeholders

I'm tryin to override Flask-Admin's edit_form() in order to dynamically populate a SelectField. I managed to do so this way

class ProductForm(Form):
    order = IntegerField('order')
    name = TextField('name')
    category = SelectField('category', choices=[])
    image = ImageUploadField(label='Optional image',
                             base_path=app.config['UPLOAD_FOLDER_ABS'],
                             relative_path=app.config['UPLOAD_FOLDER_R'],
                             max_size=(200, 200, True),
                             endpoint='images',
                             )

class ProductsView(MyModelView):
    create_template = 'admin/create-products.html'
    edit_template = 'admin/edit-products.html'
    column_list = ('order', 'name', 'category', 'image')
    form = ProductForm
    column_default_sort = 'order'

    def edit_form(self, obj):
        form = self._edit_form_class(get_form_data(), obj=obj)
        cats = list(db.db.categories.find())
        cats.sort(key=lambda x: x['order'])
        sorted_cats = [(cat['name'], cat['name']) for cat in cats]
        form.category.choices = sorted_cats
        form.image.data = obj['image']
        return form

The problem is now the form in the /edit/ view defaults name and order fields to empty unless i add these two lines to edit_form():

form.name.data = obj['name']
form.order.data = obj['order']

But if i do so the form will ignore every change (because i set form.field_name.data already?)

How do I preserve the old form values as "placeholders" while correctly overriding edit_form()?

Upvotes: 2

Views: 2079

Answers (1)

ehambright
ehambright

Reputation: 1593

I had a similar problem and thanks to the answer here I solved it;

Basically you set the default for the fields, and then call the individual fields process() method, passing in the currently set value.

from wtforms.utils import unset_value

form.name.default = obj['name']
form.name.process(None, form.name.data or unset_value)
form.order.default = obj['order']
form.order.process(None, form.order.data or unset_value)

Upvotes: 2

Related Questions