自定义Flask-Admin表单,其中一些选择字段选项根据另一个选择字段设置

时间:2015-08-01 17:37:31

标签: flask flask-admin

我正在尝试使用Flask-Admin为下面显示的模型 Matriline 创建一个创建/编辑表单。此模型有一个字符串字段 name 和一个字段 pod_id ,外键约束到另一个模型 Pod ,它本身有一个外键字段到 Clan 模型。

Flask-Admin创建的默认表单显示名称字段和 Pod 实例的选择字段,但我想添加字段 Clan ,它会根据所选的 Clan 实例重置 Pod 列表。

要添加 Clan 字段,我会覆盖 Matriline 的默认ModelView,并为所有Clan实例添加一个额外的选择字段 Clan ,如在下面的MatrilineView视图中显示。

现在我需要在渲染的表单中添加一些Ajax代码,以便在每次选择新的clan时重置pod列表。

我是否必须使用包含Ajax代码的自定义表单完全替换默认表单?或者使用Flask-Admin有更简单的方法吗?

<b>models.py</b>

...

class Matriline(db.Model):
    __tablename__ = 'matriline'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(64))
    pod_id = db.Column(db.Integer, db.ForeignKey('pod.id'))

    def __unicode__(self):
        return self.name


class Pod(db.Model):
    __tablename__ = 'pod'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(64))
    matrilines = db.relationship('Matriline', backref='pod', lazy='select')
    clan_id = db.Column(db.Integer, db.ForeignKey('clan.id'))

    def __unicode__(self):
        return self.name


class Clan(db.Model):
    __tablename__ = 'clan'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(64))
    pods = db.relationship('Pod', backref='clan', lazy='select')

    def __unicode__(self):
        return self.name

...

<b>views.py</b>

from flask_admin.contrib import sqla
from wtforms import SelectField
from orcall import models


class MatrilineView(sqla.ModelView):
    column_hide_backrefs = False
    form_extra_fields = {
        'clan': SelectField('Clan',
            choices=[ (c.id, c.name) for c in models.Clan.query.all()])
    }
    column_list = ('name', 'pod', 'clan')

...

1 个答案:

答案 0 :(得分:4)

您需要使用 QuerySelectField 。例如:

from flask.ext.admin.form import Select2Widget

class MatrilineView(sqla.ModelView):
    column_hide_backrefs = False
    form_extra_fields = {
        'clan': sqla.fields.QuerySelectField(
            label='Clan',
            query_factory=lambda: Clan.query.all,
            widget=Select2Widget()
        )
    }
    column_list = ('name', 'pod', 'clan')