Python:无法为FlaskForm动态设置属性吗? [英] Python: Couldn't dynamically set attributes to a FlaskForm?

查看:89
本文介绍了Python:无法为FlaskForm动态设置属性吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将属性动态设置为这样的FlaskForm

I want to set attributes dynamically to a FlaskForm like this

form = ModelForm(request.form)

文件form.py

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

但是它只能第二次运行,第一次运行,它无效.

But it only work for the second time running, the first time running, it doesn't work.

我真的不明白python构造函数是如何工作的. 像这样发布,原因是

I really don't understand how python constructor works. As this post, it said because

当您执行setattr(A,p,v)时,A类没有完全初始化 在那里.

class A is not fully initialized when you do your setattr(A, p, v) there.

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

But in other languages, the object have to be created after constructor finished, and it has full class variables, properties declared in the constructor ?

例如,它可以工作并可以打印a.key.那么flask构造函数和这个有什么区别?

For example, it works and can print a.key. So what's difference there in the flask constructor and this?

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

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

推荐答案

A类未完全初始化

class A is not fully initialized

表示,当您使用form=ModelForm()创建类的第一个实例时,就开始向当前实例化的类添加属性.我不知道这在Python内部到底是如何工作的.但是由于您说这只能在第二次运行中起作用,所以我想首先使用为该类定义的所有属性创建对象,然后执行__init__.因此,新属性被添加到了后期.

means, when you create your first instance of your class with form=ModelForm(), you start adding attributes to the class you are currently instancing from. I don't know, how exactly this works internally in Python. But since you say this only works in the second run, I guess the object is first created with all attributes defined for the class, then __init__ is executed. So the new attributes are added to late.

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

In other words: Your are trying to change the class definition after you already created an instance of it. You need to add all your attributes, before you instantiate.

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

Now what you need to do is: first define the class without any dynamic fields. Then, after the class definition, you add the loop with your dynamic fields.

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

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

Or if you need to add some other stuff in class definition:

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

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

然后,您可以在视图功能的某个位置照常使用form = ModelForm(request.form).

And then, somewhere in your view function, you can use form = ModelForm(request.form) as usual.

通常,您会事先知道需要哪些字段.该表格只是回答从GET请求中得到的内容.所以这应该没问题. 但是也许您在客户端添加了一些带有一些JS的其他字段,但服务器尚不知道.在这种情况下,您可以尝试将类定义放入处理POST请求的view函数的本地范围.

Usually you know what fields you need beforehand. The form just answers on what it got from the GET request. So this should be fine. But maybe you added some more fields with some JS on client side, which the server does not know about (yet). In that case you might try to put the class definition into the local scope of the view function which handles the POST request.

这篇关于Python:无法为FlaskForm动态设置属性吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆