2012-07-24 90 views
9

我如何動態地創建幾個帶有不同問題的表單域,但答案相同?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) 

回答

11

這是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://stackoverflow.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://stackoverflow.com/questions/2583620/dynamically-create-class-attributes – TomSawyer 2017-10-09 09:09:58

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