Показать поля на основе значения другого поля в администраторе фляги - PullRequest
0 голосов
/ 27 января 2019

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

Например,

, если у меня есть таблица продуктов, с TYPE, имеющей либо "автомобиль", либо "вертолет".Столбцы:

vertical speed, horizontal speed и horn amplitude.

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

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

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

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

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

1 Ответ

0 голосов
/ 27 января 2019

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

На 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()

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

...