Python:无法动态设置FlaskForm的属性?

时间:2017-10-09 08:01:12

标签: python constructor attributes flask-wtforms

我想动态地将属性设置为像

这样的FlaskForm
form = ModelForm(request.form)

file form.py

class ModelForm(FlaskForm):
    def __init__(self, postData):
        super(ModelForm, self).__init__()
        for p in postData:
            setattr(ModelForm, p, StringField(p, validators=[InputRequired()]))

但它只适用于第二次运行,第一次运行时,它不起作用。

我真的不明白python构造函数是如何工作的。 正如这个post,它说因为

  当您执行setattr(A,p,v)时,

类A未完全初始化   那里。

但是在其他语言中,必须在构造函数完成后创建对象,并且它具有完整的类变量,在构造函数中声明的属性?

例如,它可以工作并可以打印a.key。那么在烧瓶构造函数中有什么不同呢?

class A(object):
    def __init__(self):
        self.a = 'i am a accessor'
        setattr(self, 'key', 'value')

a = A()
print a.a
print a.key

1 个答案:

答案 0 :(得分:1)

  

A类未完全初始化

表示,当您使用__init__创建第一个班级实例时,您开始向当前正在实例化的班级添加属性。我不知道,这在Python内部是如何工作的。但是既然你说这只适用于第二次运行,我想首先创建的对象具有为类定义的所有属性,然后执行ModelForm = FlaskForm for p in postData: setattr(ModelForm, p, StringField(p, validators=[InputRequired()])) 。所以新属性会被添加到最近。

换句话说:您正在尝试在之后更改类定义,您已经创建了它的实例。您需要在实例化之前添加所有属性

现在您需要做的是:首先定义没有任何动态字段的。然后,类定义之后,使用动态字段添加循环。

class ModelForm(FlaskForm):
    def foo(self):
        return 'bar'

for p in postData:
    setattr(ModelForm, p, StringField(p, validators=[InputRequired()]))

或者如果您需要在课程定义中添加其他内容:

form = ModelForm(request.form)

然后,在您的视图功能中,您可以像往常一样使用position: absolute; top: xxx left: xxx

通常您事先知道自己需要哪些字段。表单只是回答了GET请求的内容。所以这应该没问题。 但也许你在客户端添加了一些更多的字段,服务器还不知道(还)。在这种情况下,您可能会尝试将类定义放入处理POST请求的视图函数的本地范围。