根据flask admin中另一个字段的值显示字段

时间:2019-01-26 21:48:27

标签: flask flask-sqlalchemy flask-wtforms flask-admin

我有带有“ TYPE”列和许多其他字段的数据库表。在许多情况下,某些列值基于'TYPE'的值为空。

例如

如果我有一个产品表,其中TYPE具有“ car”或“ helicopter”。列为:

vertical speedhorizontal speedhorn amplitude

在“汽车”类型的情况下,垂直速度应始终为null,在“直升机”类型的情况下,horn amplitude应始终为空。

在flask admin中,是否有任何方法可以根据当前选定的TYPE的值来隐藏要提交的字段?

如果是UI级别更改(即出于安全性/一致性目的不需要后端验证)就可以了。

在我的现实生活场景中,有10列,其中5+是null,因此如果可以在UI中删除这些字段将非常有帮助(因为这会使表格变得很长,容易出错)。

我正在使用烧瓶sqlalchemy作为烧瓶管理员的后端。

1 个答案:

答案 0 :(得分:2)

有趣的问题。这是一个可行的解决方案。因此,基本上您有产品类型,每种类型都有某些有效属性(例如汽车和喇叭响度)。无论类型如何,您都可以拥有常规属性,例如每个产品的名称。

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

请注意,这仅适用于编辑表单,因为仍不确定产品的类型,所有属性仍将显示在创建表单上。