Hi Stackoverflow community,
I'm trying to learn Flask-Admin. The documentation is a very good start, however I've found a very specific use-case that I'm not able to resolve. I have a table in PostgreSQL for variables. I've chosen for this approach since I've got quite a lot of variables but they don't share the same attributes (for example, the region doesn't have the property email).
Variable | Value |
---|---|
User1 | {"name": "Name", "email": "test@example.com"} |
Region1 | {"region": "Europe", "name": "DHL", "color": "blue"} |
I'd like to have the functionality that the end-user can edit the variables themselves. They don't have any knowledge about JSON of course so it would be nice to render out the fields. Currently it's one field where the JSON value is. It would be perfect if there's a field for every item in the edit view in Flask-Admin. For example this would mean that editing the User1
variable shows 2 fields, one for name and one for email.
Finally found a solution after months!
Variable = Base.classes.variables
class VariableView(ModelView):
list_columns = ["variable", "value"]
form_columns = ["variable", "value"]
column_default_sort = ("variable", False)
column_filters = ["variable"]
column_sortable_list = ["variable"]
column_searchable_list = ["variable"]
column_formatters = {
"variable": lambda view, context, model, name: model.variable.replace(
"_", " "
).capitalize(),
}
def edit_form(self, obj):
class VariableForm(FlaskForm):
pass
setattr(
VariableForm,
"variable",
StringField("Variable", validators=[Optional()], default=obj.variable),
)
try:
json_data = json.loads(obj.value)
for key in json_data:
setattr(
VariableForm,
key,
StringField(
key.capitalize(),
validators=[Optional()],
default=json_data[key],
),
)
except json.decoder.JSONDecodeError:
setattr(
VariableForm,
"Value",
StringField("Label", validators=[Optional()], default=obj.value),
)
return VariableForm(obj=obj)
def on_model_change(self, form, model, is_created):
# Update the model with the data from the form
json_output = {}
for field in form:
if field.name == "value":
return model
if field.name != "variable" and field.name != "csrf_token":
json_output[field.name] = field.data
model.value = json.dumps(json_output)
return model
admin.add_view(VariableView(Variable, user.session, name="Variables"))