【问题标题】:Show fields based on the value of another field in flask admin根据烧瓶管理中另一个字段的值显示字段
【发布时间】:2019-01-26 21:48:27
【问题描述】:

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

例如

如果我有一个产品表,TYPE 有“汽车”或“直升机”。列是:

vertical speedhorizontal speedhorn amplitude

对于 'car' 类型,垂直速度应始终为 null ,对于 'helicopter' ,horn amplitude 应始终为空。

在flask admin中,有没有办法根据当前选择的TYPE的值隐藏字段以防止提交?

如果是 UI 级别更改(即出于安全性/一致性目的不需要后端验证),那很好。

在我的现实生活场景中,有超过 10 个列,其中 5+ 为 null,因此如果可以在 UI 中删除这些字段将非常有帮助(因为它使表单很长并且容易错误)。

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

【问题讨论】:

  • 您可以覆盖创建和编辑模板并添加一些 jaascript 以根据所选类型(汽车、直升机)隐藏字段
  • 任何不涉及覆盖模板的选项?

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


【解决方案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()

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

【讨论】:

  • 任何前端方式使其也适用于创建表单?
  • 不,您必须自己实现,因为尚不确定产品类型将是什么,因此不确定创建实例时要显示哪些字段。你需要 javascript。
猜你喜欢
  • 2021-08-31
  • 2019-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多