Показать поля на основе значения другого поля в администраторе фляги

У меня есть таблицы базы данных со столбцом «ТИП» и многими другими полями. Во многих случаях определенные значения столбца являются нулевыми в зависимости от значения «TYPE».

Например.

если у меня есть таблица продуктов, где TYPE имеет либо «автомобиль», либо «вертолет». Столбцы:

vertical speed, horizontal speed и horn amplitude.

В случае типа "автомобиль" вертикальная скорость всегда должна быть null, а в случае "вертолета" horn amplitude всегда должен быть нулевым.

В администраторе фляги есть ли способ скрыть поля от отправки на основе выбранного в данный момент значения TYPE?

Это нормально, если это изменение уровня пользовательского интерфейса (т. е. проверка серверной части не требуется для целей безопасности/непротиворечивости).

В моем реальном жизненном сценарии есть более 10 столбцов, из которых 5+ являются null в случаях, поэтому было бы очень полезно, если бы эти поля можно было удалить в пользовательском интерфейсе (поскольку это делает форму очень длинной и подверженной ошибкам).

Я использую flask sqlalchemy в качестве бэкэнда для своего администратора flask.

🤔 А знаете ли вы, что...
С Flask можно создавать веб-приложения с поддержкой многоязычности и локализации.


2
1 344
1

Ответ:

Забавный вопрос. Вот рабочее решение. Таким образом, в основном у вас есть типы продуктов, и каждый тип имеет определенные допустимые атрибуты (например, автомобиль и громкость гудка). Вы также можете иметь общие атрибуты независимо от типа, например. название каждого продукта.

На form_prefill вы проверяете, какие поля действительны для типа продукта. Затем вы выбрасываете недопустимые поля из формы и снова возвращаете форму. Это на самом деле довольно просто.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import flask_admin as admin
from flask_admin.contrib import sqla

app = Flask(__name__)
app.secret_key = 'arstt'
db = SQLAlchemy(app)

class Product(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String)
    name = db.Column(db.String)
    vertical_speed = db.Column(db.Integer)
    rotor_rpm = db.Column(db.Integer)
    honking_loudness = db.Column(db.Integer)

    def __str__(self):
        return "{}".format(self.name)

class ProductView(sqla.ModelView):
    general_product_attributes = ['name']
    product_attributes_per_product_type_dict = {
        'driving': ['honking_loudness'],
        'flying': ['rotor_rpm', 'vertical_speed']
    }

    def on_form_prefill(self, form, id):
        product = self.get_one(id)
        form_attributes = self.general_product_attributes + self.product_attributes_per_product_type_dict[product.type]
        for field in list(form):
            if field.name not in form_attributes:
                delattr(form, field.name)
        return form

db.create_all()
admin = admin.Admin(app, name='Example: SQLAlchemy', template_mode='bootstrap3')
admin.add_view(ProductView(Product, db.session))
helicopter = Product(type='flying', name='helicopter1', vertical_speed=99)
car = Product(type='driving', name='car2', honking_loudness=33)
db.session.add(helicopter)
db.session.add(car)
db.session.commit()

Обратите внимание, что это работает только для формы редактирования, все атрибуты по-прежнему отображаются в форме создания, потому что пока неизвестно, какого типа будет продукт.