title: Flask-WTF SelectMultipleField populates with database IDs instead of names
body: <p><em>I would like to preface this with saying that english is not my mother tongue, if any of my explanations are vague or don't make sense, please let me know and I will attempt to make them clearer.</em></p>
  
  <p>I have an issue with populating a <code>SelectMultipleField</code> with the correct data in Flask-WTF. As can be seen in the code below, I pass the user object to the form. This works flawlessly as it fills in all fields when the page is rendered. The issue I run into is that the <code>SelectMultipleField</code> is populated with role IDs and not the names of the roles. </p>
  
  <p>In the forms section I generate a list, <code>choices</code>, which hold all the available choices that should be displayed. I can invert this to <code>choices.append((role.id, role.name))</code> and it will populate the field with names instead of IDs. However, if I do that the roles assigned to the user object (from the database) will not show up as preselected. </p>
  
  <p>How can I make it so that the field is prepopulated with names and not IDs and keep the assigned roles preselected?</p>
  
  <p>Any guidance or nudge in the right direction will be greatly appreciated. If any information is lacking, that I did not think to add, please let me know and I'll add it.</p>
  
  <pre><code># Models
  class Role(db.Document, RoleMixin):
      meta = {'collection': 'role'} 
      name = db.StringField(max_length=80, unique=True)
      description = db.StringField(max_length=255)
  
      def __repr__(self):
          return '&lt;Role {}&gt;'.format(self.name)
  
      def __str__(self):
          return self.name
  
  class User(db.Document, UserMixin):
      meta = {'collection': 'User'}   
      first_name = db.StringField(max_length=30)
      last_name = db.StringField(max_length=30)
      email = db.StringField(max_length=120)
      password_hash = db.StringField(max_length=255)
      active = db.BooleanField(default=True)
      roles = db.ListField(db.ReferenceField(Role), default=[])
  
      def __repr__(self):
          return '&lt;User {}&gt;'.format(self.email)
  
      def __str__(self):
          return self.email
  
  # Forms
  class EditUserForm(FlaskForm):
      choices = []
      for role in Role.objects:
          choices.append((role.name, role.id))
  
      first_name = StringField('First name', validators=[DataRequired()])
      last_name = StringField('Last name', validators=[DataRequired()])
      email = StringField('Email', validators=[DataRequired(), Email()])
      password = PasswordField('Password')
      password2 = PasswordField('Repeat password', validators=[EqualTo('password')])
      roles = SelectMultipleField('User roles', choices=choices)
      submit = SubmitField('Save')
  
  # Routes
  @app.route('/users/edit/&lt;id&gt;', methods=['GET', 'POST'])
  @roles_required('admin')
  def edit_user(id):
      user = User.objects(id=id).first()
      form = EditUserForm(obj=user)
  
      if form.validate_on_submit() and request.method == 'POST':
          user.first_name=form.first_name.data
          user.last_name=form.last_name.data
          user.email=form.email.data
          user.roles = []
  
          for role in form.roles.data:
              r = Role.objects(name=role).first()
              user.set_role(r.id)
  
          if form.password.data:
              user.set_password(form.password.data)
  
          user.save()
          return redirect(url_for('users'))
  
      return render_template('edit_user.html', title='Edit user', user=user, form=form)
  </code></pre>
  
  <p>Template:</p>
  
  <pre><code>{% extends "layout.html" %}
  {% set active_page = "edit_user" %}
  {% block jumbotron %}
  
      &lt;h1&gt;{{ title }}&lt;/h1&gt;
      &lt;form action="" method="post"&gt;
          {{ form.hidden_tag() }}
          &lt;p&gt;
              {{ form.first_name.label }}&lt;br&gt;
              {{ form.first_name(size=32) }}&lt;br&gt;
              {% for error in form.first_name.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;
              {{ form.last_name.label }}&lt;br&gt;
              {{ form.last_name(size=32) }}&lt;br&gt;
              {% for error in form.last_name.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;
              {{ form.email.label }}&lt;br&gt;
              {{ form.email(size=32) }}&lt;br&gt;
              {% for error in form.email.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;
              {{ form.password.label }}&lt;br&gt;
              {{ form.password(size=32) }}&lt;br&gt;
              {% for error in form.password.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;
              {{ form.password2.label }}&lt;br&gt;
              {{ form.password2(size=32) }}&lt;br&gt;
              {% for error in form.password2.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;
              {{ form.roles.label }}&lt;br&gt;
              {{ form.roles(size=32) }}&lt;br&gt;
              {% for error in form.roles.errors %}
              &lt;span style="color: red;"&gt;[{{ error }}]&lt;/span&gt;
              {% endfor %}
          &lt;/p&gt;
          &lt;p&gt;{{ form.submit() }}&lt;/p&gt;
      &lt;/form&gt;
  
  {% endblock %}
  </code></pre>
  
  <p>I attempted to create my own object, with the code below, to pass to the form, however I was unsuccessful. When passing that object to the form, no fields were populated.</p>
  
  <pre><code>user = User.objects(id=id).first()
  temps = []
  
  u = user.to_mongo()
  u['_id'] = {'$oid': str(u['_id'])}
  temp_roles = []
  for role in user.roles:
      r = role.to_mongo()
      r['_id'] = {'$oid': str(r['_id'])}
      temp_roles.append(r)
  
  u['roles'] = temp_roles
  </code></pre>