WTForm not displayed, got python code instead
Question: I’m making a form for flask using WTForms. Here is the corresponding code :

    
    
    class UploadForm(flask.ext.wtf.Form):
        def __init__(self,year):
            flask.ext.wtf.Form.__init__(self)
            self.year=year
            subjects = app.config["SUBJECTS"][year]
            self.fichier = wtforms.fields.FileField(u'Fichier')
            self.subject = wtforms.fields.SelectField(u'Matière', choices=subjects)
            self.submit = wtforms.fields.SubmitField(u'Envoyer')
    
    @app.route('/upload/<year>')
    def upload(year):
        print year
        form = UploadForm(year)
        return flask.render_template('upload.html', form=form)
    

And here is the template `upload.html` :

    
    
    {% extends "base.html" %}
    {% block content %}
      <h2>Upload</h2>
      <form action="{{ url_for('get', year='1A') }}" method="post"
              enctype="multipart/form-data">
        {{ form.hidden_tag() }}
    
        {{ form.fichier.label }}
        {{ form.fichier }}
    
        {{ form.subject.label }}
        {{ form.subject }}
    
        {{ form.submit }}
      </form>
    {% endblock %} 
    

But when I run it, the form isn’t displayed, and instead I have this :

    
    
    <UnboundField(FileField, (u'Fichier',), {})> <UnboundField(SelectField, (u'Mati\xe8re',), {'choices': [('MA111', 'MA111'), ('NE111', 'NE111')]})>  <UnboundField(SubmitField, (u'Envoyer',), {})> 
    

Can someone help me to fix it ?


Answer: Your issue is that you are creating the form without any fields and then
adding unbound fields behind its back in your `UploadForm.__init__` method.
The `wtforms.form.Form` class actually does a lot of metaclass magic behind
the scenes. The way to do what you are doing is as follows:

    
    
    from flask import render_template
    from flask.ext.wtf import Form
    from wtforms.fields import FileField, SelectField, SubmitField
    
    class UploadForm(Form):
        """This seemingly static class will be transformed
        by the WTForms metaclass constructor"""
    
        fichier = FileField(u'Fichier')
        subject = SelectField(u'Matière')
        submit = SubmitField(u'Envoyer')
    
    
    @app.route('/upload/<year>')
    def upload(year):
        subjects = app.config['SUBJECTS'][year]
    
        form = UploadForm()
        # We can set the choices dynamically, based on year
        form.subject.choices = subjects
    
        return render_template('upload.html', form=form)
    

