Question

I have a User model class and password is one attribute among many. I am using Flask web framework and Flask-Admin extension to create the admin view of my model classes. I want to make certain fields in the admin view like password non editable or not show them at all. How do I do it?

I can make the fields not show up in the normal view but when I click on the edit button of any record in the table, all fields show up and are editable.

Was it helpful?

Solution

You should extend your view from ModelView and overwrite the necessary fields.

In my class it looks like this:

class UserView(ModelView):

    column_list = ('first_name', 'last_name', 'username', 'email')
    searchable_columns = ('username', 'email')
# this is to exclude the password field from list_view:
    excluded_list_columns = ['password']
    can_create = True
    can_delete = False
# If you want to make them not editable in form view: use this piece:
    form_widget_args = {
        'name': {
            'readonly': True
        },
    }

Hope this helps! For more information check out the documentation:

OTHER TIPS

Here is a solution that expands upon Remo's answer and this so answer. It allows for different field_args for edit and create forms.

Custom Field Rule Class

from flask_admin.form.rules import Field

class CustomizableField(Field):
    def __init__(self, field_name, render_field='lib.render_field', field_args={}):
        super(CustomizableField, self).__init__(field_name, render_field)
        self.extra_field_args = field_args

    def __call__(self, form, form_opts=None, field_args={}):
        field_args.update(self.extra_field_args)
        return super(CustomizableField, self).__call__(form, form_opts, field_args)

UserView Class

class UserView(ModelView):

    column_list = ('first_name', 'last_name', 'username', 'email')
    searchable_columns = ('username', 'email')

    # this is to exclude the password field from list_view:
    excluded_list_columns = ['password']
    can_create = True
    can_delete = False

    # If you want to make them not editable in form view: use this piece:
    form_edit_rules = [
        CustomizableField('name', field_args={
            'readonly': True
        }),
        # ... place other rules here
    ]

Yet another way to work the problem around is to use Flask-Admin ModelView method called on_form_prefill to set readonly property argument. According to Flask-Admin Docs:

on_form_prefill(form, id)

Perform additional actions to pre-fill the edit form.

Called from edit_view, if the current action is rendering the form rather than receiving client side input, after default pre-filling has been performed.

In other words, this is a trigger, which is run when opening only Edit form, not the Create one.

So, the solution for the example used above would be:

class UserView(ModelView):
    ...
    def on_form_prefill(self, form, id):
        form.name.render_kw = {'readonly': True}

The method is run after all other rules applied, so none of them are broken, including set of columns.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top