Everything on the WTForm works correctly and I've searched many WTForms QuerySelectedField questions here as well.
My form presents all records as it should correctly except for this "Country" pull-down QuerySelectedField form tool, which doesn't show the correct country name.
This form should have presented "Canada" because the user.country database field contains Canada's country_id = 123 and not Afghanistan's 115. Afghanistan is just the top/first record of the select list.
I'm sure it's a small and obvious problem, but I can't see a solution (other than a bug) and I hope someone out there has fixed this problem already.
WTForms is version 2.3.3
WTForms-SQLAlchemy is version 0.2
forms.py
class UserDetailForm(FlaskForm):
username = StringField('Username', id='username' , validators=[DataRequired()])
country = QuerySelectField(query_factory=lambda: Country.query.filter(Country.region!="Aggregates"), get_pk=lambda x: x.id, get_label="name")
Form.html
{{ form.country(class="selectpicker", value = current_user.country) }}
The Network view in Chrome Inspect tool shows that the form calls:
<select class="selectpicker" id="country" name="country" value="123"><option value="115">Afghanistan</option><option value="123">Canada</option></select>
Models.py
class User(db.Model, UserMixin):
__tablename__ = 'User'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(22), primary_key=True, unique=True)
country = Column(Integer)
def __init__(self, **kwargs):
for property, value in kwargs.items():
if hasattr(value, '__iter__') and not isinstance(value, str):
value = value[0]
if property == 'password':
value = hash_pass( value ) # we need bytes here (not plain str)
setattr(self, property, value)
def __repr__(self):
return str(self.username)
Routes.py
@blueprint.route('/profile', methods=['GET', 'POST'])
@login_required
def profile():
# user_detail_form = UserDetailForm(request.form)
form = UserDetailForm(request.form)
if 'profile' in request.form:
...
return render_template('page-user.html', msg='Profile changes made', form=form)
## This works correctly!
else:
sidetog = 'profile'
# return render_template('page-user.html', value=sidetog, form=user_detail_form)
return render_template('page-user.html', value=sidetog, form=form)
## This works correctly also, for everything except the country pull-down value
Data All country code ids here are integers.
country.name country.id
Canada 123
Afghanistan 115
user.country
123
