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 o
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.
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)
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
]
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:
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.