WTForms创建可变数量的字段

问题描述:

我如何动态地创建几个带有不同问题的表单域,但答案相同?WTForms创建可变数量的字段

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) 

这是in the docs一直。

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 comment

This is not a bug, it is by design. There are a lot of problems with adding fields to instantiated forms - For example, data comes in through the Form constructor.

If you reread the thread you link, you'll notice you need to derive the class, add fields to that, and then instantiate the new class. Typically you'll do this inside your view handler.

+0

我不清楚这个解决方案是否与我的问题有关我在我的Post模型中有关系叫做标签......当我调用PostForm生成标签时,查询会显示查询结果如何运行查询并将结果作为逗号描述字符串发送到邮政标签字段?这是我的[发布的问题](http://*.com/questions/23251470/how-to-send-query-results-to-a-wtform-field)。 – jwogrady 2014-04-23 23:21:21

+0

通过这种方式,它不能解决问题,你不能像form.py那样分开形式文件,然后是'a = Form(params)',定义类内部的方法不被认为是好的做法? https://*.com/questions/2583620/dynamically-create-class-attributes – TomSawyer 2017-10-09 09:09:58

就快:

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) 
+0

感谢您的回复。如果我这样做,所有字段显示为“UnboundFields”,并且不会与表单一起呈现。 – ash 2012-07-24 22:39:41

+0

@ash - 道歉 - 我认为它需要'__new__'而不是'__init__'。我用新的(尚未测试的)代码更新了我的答案。让我知道,如果它不适合你。 – 2012-07-25 02:06:53

+0

再次感谢您的回复,不幸的是,这不起作用(我不得不做'返回超(VariableForm,CLS).__新__(CLS,** KWARGS)'。我一直在寻找https://bitbucket.org/简单代码/ wtforms/src/a5f9e30260cc/wtforms/form.py但我不知道发生了什么,我将不得不继续尝试其他的东西 – ash 2012-07-25 05:28:25