title: Flask-WTF model_form, Sqlalchemy, and foreign keys
body: <p>I'm trying to take my model and generate forms using wtform's model_form for sqlalchemy.  I would like the fields with a foreign key constraint to be a select list of all the items in that table.</p>
  
  <p>So far I can either get nothing or a simple text input for the literal foreign key, and I'm a little lost.</p>
  
  <p>OK, so I have a relatively simple data model here.  For this I can reduce it down to where I have types of hardware, and their support statuses.  I want to be able to add support statuses in the future, and provide more useful descriptions for them.</p>
  
  <pre><code>from . import db
  class Status(db.Model):
      """Support status"""
      __tablename__ = 'status'
      id = db.Column(db.Integer, primary_key = True)
      name = db.Column(db.String(64), unique=True)
      description = db.Column(db.Text)
      def __repr__(self):
          return self.name
  
  class Hardware(db.Model):
      """Hardware"""
      __tablename__ = 'hardware'
      id = db.Column(db.Integer, primary_key = True)
      name = db.Column(db.String(64), unique=True)
      description = db.Column(db.Text)
      status = db.Column(db.Integer, db.ForeignKey('status.id'))
      ...
      def __repr__(self):
          return self.name
  </code></pre>
  
  <p>Groovy.  </p>
  
  <p>Now my view looks like so:</p>
  
  <pre><code>from flask import render_template, request, flash, redirect, url_for
  from flask_wtf import Form
  from wtforms.ext.sqlalchemy.orm import model_form
  from . import db, app
  import models
  ...
  @app.route('/edit/status/', defaults={'id': None}, methods=['GET', 'POST'])
  @app.route('/edit/status/&lt;int:id&gt;', methods=['GET', 'POST'])
  def edit_hardware(id=None):
      HardwareForm = model_form(models.Hardware, base_class=Form,
              db_session=db.session, exclude_fk=False)
      if id == None:
          model = models.Hardware()
      else:
          model = models.Hardware.query.get(id)
      form = HardwareForm(request.form, model)
      if form.validate_on_submit():
          form.populate_obj(model)
          db.session.add(model)
          db.session.commit()
          flash("yay!")
      return render_template('forms.html', form=form)
  </code></pre>
  
  <p>So I've obviously tried the exclude_fk maneuver, but that just gives me a text field for an integer.</p>
  
  <p>I feel like I need to be telling something to use the name field from Status, although I guess that could be derived from the <strong>repr</strong> method.</p>
  
  <p>Do I need to drop the exclude_fk and manually add a QuerySelectField to the form?  Is there something I should pass in field_args?  Am I doing something dumb?</p>
  
  <p>I'd like to do as little manual intervention as possible here, and I feel like this is a fairly textbook scenario.</p>