pallets-eco / flask-admin

Simple and extensible administrative interface framework for Flask
https://flask-admin.readthedocs.io
BSD 3-Clause "New" or "Revised" License
5.79k stars 1.57k forks source link

Adding 'scaffold_form' makes 'form_columns' ignored #2545

Open dhait opened 2 weeks ago

dhait commented 2 weeks ago

I've added a scaffold_form() function on my view, in order to override the querying of a specific child field. But it is put at the bottom of the form, instead of at the top, as requested by 'form_columns'.

# In the ShareView class -->

    form_widget_args = {
        'company' : { 'disabled': True },
    }

    def scaffold_form(self):
        form_class = super(ShareView, self).scaffold_form()

        # Override the 'company' field to only display the currently assigned company
        form_class.company = QuerySelectField(
            'Company',
            query_factory=lambda: self._get_current_company(),
            allow_blank=False,
            get_label='name'
        )
        return form_class

    def _get_current_company(self):
        # Return a query that only contains the current company (no query for all)
        if self.model.company:
            return Company.query.filter_by(id=self.model.company_id)
        return Company.query.filter_by(id=None)  # Return empty if no company is assigned

    form_columns = ('company', 'stock_exchange','name','code', 'isin', 'status', 'slug', 'remote_id', 'price',
         'in_issue','dividend_cover','stamp_duty_exempt')

I expect that the 'Company' field will be at the top of the 'edit' form (disabled). Instead, it is at the very bottom after all the other fields.

Environment:

samuelhwilliams commented 1 week ago

Flask-Admin currently relies on WTForm's ordering when rendering fields.

Flask-Admin adds fields to the form based on form_columns, and generally WTForms respects this, so I suspect this bug is caused by the form being generated and then you "adding" (overriding) the company field, which maybe sends it to the back of the list of fields on the form.

It does look like flask-admin docs say form_columns controls the rendering order of fields, so I think we should fix this.

At a glance this appears to be the likely culprit: https://github.com/pallets-eco/flask-admin/blob/2fae681e641d4377f60e9c514110809b24a65ed0/flask_admin/templates/bootstrap4/admin/lib.html#L195-L202

In the mean time, a workaround might be to set form_rules as per https://flask-admin.readthedocs.io/en/latest/api/mod_contrib_sqla/#flask_admin.contrib.sqla.ModelView.form_rules. As form_rules overrides the ordering of fields that comes from wtforms.