2012-07-24 19 views
9

¿Cómo crearía dinámicamente unos pocos campos de formulario con diferentes preguntas, pero las mismas respuestas?WTForms crea un número variable de campos

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) 

Respuesta

11

Fue in the docs todo el tiempo.

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 

Lo que no se dan cuenta es que los atributos de clase deben establecerse antes de se produce ninguna ejemplificación. La claridad viene de este 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

No tengo claro si esta solución se relaciona con mi problema. Tengo etiquetas de relación llamada en mi modelo de publicación ... Cuando llamo a PostForm genera etiquetas, la consulta se muestra en su lugar de los resultados de la consulta. ¿Cómo ejecuto la consulta y envío los resultados como una secuencia delineada por comas? al campo de etiquetas de publicación? Aquí está mi [pregunta publicada] (http://stackoverflow.com/questions/23251470/how-to-send-query-results-to-a-wtform-field). – jwogrady

+0

Al hacer esto, no resuelve la pregunta, no se puede separar el archivo de formulario como 'form.py' luego' a = Form (params) ', ¿no se considera que la definición de clase dentro del método es una buena práctica? https://stackoverflow.com/questions/2583620/dynamically-create-class-attributes – TomSawyer

1

Ya casi ha terminado:

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

Gracias por la respuesta. Si hago esto, todos los campos aparecen como 'UnboundFields' y no se mostrarán con el formulario. – ash

+0

@ash - disculpas - Creo que tenía que ser '__new__' no' __init__'. He actualizado mi respuesta con un código nuevo (aún no probado). Avíseme si no funciona para usted. –

+0

Gracias de nuevo por responder, desafortunadamente, eso no funciona (tuve que hacer 'return super (VariableForm, cls) .__ new __ (cls, ** kwargs)'. He estado viendo https://bitbucket.org/ simplecodes/wtforms/src/a5f9e30260cc/wtforms/form.py pero no puedo decir lo que está pasando. Tendré que seguir probando otras cosas. – ash

Cuestiones relacionadas