13

我如何动态创建一些具有不同问题但答案相同的表单字段?

from wtforms import Form, RadioField
from wtforms.validators import Required

class VariableForm(Form):

    def __init__(formdata=None, obj=None, prefix='', **kwargs):
        super(VariableForm, self).__init__(formdata, obj, prefix, **kwargs)
        questions = kwargs['questions']
        // How to to dynamically create three questions formatted as below?

    question = RadioField(
            # question ?,
            [Required()],
            choices = [('yes', 'Yes'), ('no', 'No')],
            )

questions = ("Do you like peas?", "Do you like tea?", "Are you nice?")  
form = VariableForm(questions = questions)
4

3 回答 3

17

它一直在文档中。

def my_view():
    class F(MyBaseForm):
        pass

    F.username = TextField('username')
    for name in iterate_some_model_dynamically():
        setattr(F, name, TextField(name.title()))

    form = F(request.POST, ...)
    # do view stuff

我没有意识到必须在任何实例化发生之前设置类属性。清晰来自这个bitbucket 评论

这不是错误,而是设计使然。向实例化表单添加字段存在很多问题 - 例如,数据通过 Form 构造函数进入。

如果您重新阅读链接的线程,您会注意到您需要派生类,向其中添加字段,然后实例化新类。通常,您将在视图处理程序中执行此操作。

于 2012-07-26T04:42:02.343 回答
1

您快到了:

CHOICES = [('yes', 'Yes'), ('no', 'No')]

class VariableForm(Form):

    def __new__(cls, questions, **kwargs):
        for index, question in enumerate(questions):
            field_name = "question_{}".format(index)
            field = RadioField(question,
                                  validators=[Required()],
                                  choices=CHOICES)
            setattr(cls, field_name, field)
        return super(VariableForm, cls).__new__(cls, **kwargs)
于 2012-07-24T03:37:27.537 回答
0

就我而言,我使用了 csv 并使用 pandas 将其导入。

因此,如果需要,此解决方案甚至允许您使用不同的答案。

data=pd.read_csv("./temp.csv")
class UserForm(Form):
    for i in data:
        if data[i][0] == 'textbox':
            formElement='TextField("%s",validators=[validators.required()], default="please add content")' %(i)

        elif data[i][0] == 'radio':
            choice = list(data[i][1:].dropna().unique().tolist())
            choiceStr=''
            for k in choice:
               choiceStr +="('"+k+"','"+k+"'),"
            
            formElement = 'RadioField("%s",validators=[validators.required()],choices=[%s], default="%s")' %(i,choiceStr, choice[0])

        elif data[i][0] == 'dropdown':
            choice = list(data[i][1:].dropna().unique().tolist())
            # choice.remove('X')
            choiceStr=''
            for k in choice:
               choiceStr +="('"+k+"','"+k+"'),"
            
            formElement = 'SelectField("%s",validators=[validators.required()],choices=[%s])' %(i,choiceStr)


        exec("%s=%s" % (i,formElement))

于 2020-11-24T19:40:46.177 回答