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.76k stars 1.57k forks source link

Postgres SQLalchemy Array Issue #1986

Open jjonnyboy94 opened 4 years ago

jjonnyboy94 commented 4 years ago

When I try saving a row to the database in the admin panel I get an error stating that there is a malformed array literal. Capture Capture1 I was able to get the row saved simply enough by correcting the "[" to "{". There are 2 other issues though. 1) When I open the row back up to edit it the array is wrapped in square brackets again and will throw the same error. 2) Even if the text box is empty the error is thrown, so an empty array must be inserted instead of being able to save a null value.

ljluestc commented 1 week ago

from mongoengine import Document, ListField, StringField
from flask_admin.contrib.mongoengine import ModelView
from flask_admin.form import BaseForm
from wtforms import TextAreaField
from wtforms.validators import Optional

class MyModel(Document):
    name = StringField()
    my_array = ListField(StringField())

class MyModelForm(BaseForm):
    my_array = TextAreaField('My Array', validators=[Optional()])

    def validate_my_array(self, field):
        if field.data:
            # Convert the input from string to a list
            try:
                # Assuming input is in JSON format
                field.data = field.data.strip().replace('[', '{').replace(']', '}')
            except Exception as e:
                raise ValueError('Malformed array literal') from e

class MyModelView(ModelView):
    form = MyModelForm

    def on_model_change(self, form, model, is_created):
        # Convert empty input to None
        if not form.my_array.data:
            model.my_array = None
        else:
            # Ensure the data is stored in the correct format
            model.my_array = form.my_array.data.strip().replace('{', '[').replace('}', ']')

    def get_form(self, *args, **kwargs):
        form = super().get_form(*args, **kwargs)
        # Preprocess to display the array correctly
        if form.my_array.data:
            form.my_array.data = form.my_array.data.strip().replace('[', '{').replace(']', '}')
        return form

# Register your view
admin.add_view(MyModelView(MyModel))