2012-07-24 5 views
9

Wie würde ich dynamisch einige Formularfelder mit verschiedenen Fragen erstellen, aber die gleichen Antworten?WTForms erstellen variable Anzahl von Feldern

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) 

Antwort

11

Es war in the docs die ganze Zeit.

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 

Was habe ich nicht erkennen, ist, dass die Klassenattribute müssen vor jede Instanziierung auftritt eingestellt werden. Die Klarheit kommt davon :

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

Es ist mir nicht klar, ob diese Lösung zu meinem Problem gehört.Ich habe in meinem Post-Modell Beziehungen namens Tags ... Wenn ich PostForm Tags anrufe, wird stattdessen die Abfrage angezeigt der Abfrageergebnisse Wie führe ich die Abfrage aus und sende die Ergebnisse als durch Komma abgegrenzte Zeichenfolge in das Post-Tags-Feld? Hier ist meine [gepostete Frage] (http://stackoverflow.com/questions/23251470/how-to-send-query-results-to-a-wtform-field). – jwogrady

+0

Auf diese Weise löst es nicht eindeutig die Frage, Sie könnten die Formulardatei nicht trennen wie 'form.py', dann' a = Form (params) ', das Definieren der Klasse innerhalb der Methode wird nicht als gute Praxis betrachtet? https://stackoverflow.com/questions/2583620/dynamically-create-class-attributes – TomSawyer

1

Sie haben es fast geschafft:

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

Danke für die Antwort. Wenn ich dies tue, erscheinen alle Felder als "UnboundFields" und werden nicht mit dem Formular gerendert. – ash

+0

@ash - Entschuldigung - Ich denke, es musste "__new__' nicht" __init__' sein. Ich habe meine Antwort mit neuem (noch ungetestetem) Code aktualisiert. Lass es mich wissen, wenn es nicht für dich funktioniert. –

+0

Nochmals vielen Dank für die Antwort, leider funktioniert das nicht (ich musste 'Rückkehr super (VariableForm, cls) .__ neue __ (cls, ** kwargs)'. Ich habe auf https://bitbucket.org/ simplecodes/wtforms/src/a5f9e30260cc/wtforms/form.py aber ich kann nicht sagen, was vor sich geht Ich werde weiter versuchen müssen andere Dinge – ash

Verwandte Themen