我已经获得了带参数资源的表单LimitForm
class LimitForm(FlaskForm):
def __init__(self, resource: Resource, *args, **kwargs):
super(LimitForm, self).__init__(*args, **kwargs)
self.period.choices = Period.choices()
我想通过FormField以其他形式使用此表单作为字段。像一个
class LimitsForm(FlaskForm)
limits = FieldList(FormField(LimitForm))
但此代码引发异常 TypeError:__ init __()缺少1个必需的位置参数:' resource'
如何从LimitsForm传递资源到LimitForm?
由于
答案 0 :(得分:0)
您可能会发现,在对封闭类进行常规初始化之后,执行一些附加的逻辑会比较容易,例如最后用特殊的逻辑实现自己的LimitsForm.__init__()
。否则,您可能必须继承FieldList
和FormField
的子类,并覆盖它们的process
方法,如果您只需要为一个用例做一个简单的额外步骤,生活就会变得很复杂!
例如,我有一种情况,我想做与您要求的类似的事情,并通过FormField
传递一些特殊的kwarg。 Flask-WTF默认情况下似乎不执行此操作。在这种情况下,我使用的QuerySelectField
在调用SQLAlchemy时要传递一些特殊的过滤器。
在我的控制器中,对此的调用就像
form = CampaignForm(obj=campaign, studio=campaign.studio)
此处,工作室是特殊过滤器的一部分,仅在运行时才知道。但是,此studio
kwarg不能通过嵌套的FormField
来实现。
因为我必须扩展和重新连接Flask-WTF中的核心逻辑,才能使此kwarg通过FormField传递到GatingExtraForm
中,所以我对此问题的解决方案是:
class GatingExtraForm(FlaskForm):
class Meta:
# we do not need CSRF in sub-forms
csrf = False
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_query(studio=kwargs.get('studio'))
# when this form is nested in a FormField, the studio kwarg may not be passed to __init__,
# therefore we make this method available for some post-initialization.
def set_query(self, studio=None):
self.gating_campaign.query = db.query(InAppCampaign).filter(InAppCampaign.active)
if studio:
self.gating_campaign.query = self.gating_campaign.query.filter(InAppCampaign.studio == studio)
self.gating_campaign.query = self.gating_campaign.query.order_by(InAppCampaign.name)
gating_campaign = QuerySelectField(
"Gating Campaign",
get_label='name',
allow_blank=False,
validators=[validators.Optional()]
)
# additional fields here....
class CampaignForm(FlaskForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# because there is no naive way to pass kwargs through on FormField init,
# just do some post init special processing
self.gating_extra.form.set_query(studio=kwargs.get('studio'))
# additional fields here....
gating_extra = FormField(GatingExtraForm)
我承认,这有点骇人听闻,但有时对于少数用例来说,这是一个合理的权衡。如果事实证明这是一种常见模式,那么您可以更深入地扩展Flask-WTF。