我有一个用WTForms创建的表单(使用Flask-WTF扩展)并使用SelectMultipleField生成两组动态复选框。我有一个问题,如果我检查Orientation组中的任何框,表单没有验证,但也没有给我任何验证错误。我也没有在该领域使用任何验证器。如果我在没有从Orientation小组检查的情况下提交它,它将提交正常。如果我从Subreddit组中选择任何几乎完全相同的复选框,表单提交就好了。
这是我的表单类:
class RegistrationForm(Form):
email = StringField('Email', validators=[Required(), Length(1,64),
Email()])
username = StringField('Username', validators=[
Required(), Length(1, 64), Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0,
'Usernames must have only letters, '
'numbers, dots or underscores')])
password = PasswordField('Password', validators=[
Required(), EqualTo('password2', message='Passwords must match.')])
password2 = PasswordField('Confirm password', validators=[Required()])
sex = SelectField('Sex', choices=[('M', 'Male'), ('F', 'Female'), ('T', 'Transgendered')], validators=[Required()])
min_age = IntegerField('Minimum Age', validators=[Required()])
max_age = IntegerField('Maximum Age', validators=[Required()])
city = StringField('City', validators=[Required()])
state = SelectField('State', validators=[Required()])
location_alias = StringField('Location Aliases')
location_radius = IntegerField('Radius of matches (in miles)',
validators=[Required(), NumberRange(min=0,
max=100,
message="Radius must be between 0-100 miles.")])
orientation = SelectMultipleField('Orientation (posts you want to see)',
option_widget=widgets.CheckboxInput(),
widget=widgets.ListWidget(prefix_label=False))
subreddits = SelectMultipleField('Subreddits',
option_widget=widgets.CheckboxInput(),
widget=widgets.ListWidget(prefix_label=False))
def validate_min_age(self, field):
if field.data < 18:
raise ValidationError("Minimum age must be at least 18.")
def validate_email(self, field):
if User.query.filter_by(email=field.data).first():
raise ValidationError("We already have a user with this email address.")
def validate_username(self, field):
if User.query.filter_by(username=field.data).first():
raise ValidationError("We already have a user with this username.")
# Data for dynamic checkboxes needs to be initialized when the form is used
def __init__(self, *args, **kwargs):
Form.__init__(self, *args, **kwargs)
self.state.choices = [(s.state, s.state) for s in State.query.all()]
self.orientation.choices = [(o.orientation, o.orientation) for o in Orientation.query.all()]
self.subreddits.choices = [(s.subreddit, s.subreddit) for s in Subreddit.query.all()]
以下是我的观点,即加载此表单并调用validate_on_submit()
:
@auth.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
# get or create the location object
l = Location.query.filter_by(city=form.city.data, state=form.state.data).first()
if not l:
l = Location(city=form.city.data, state=form.state.data)
db.session.add(l)
db.session.commit()
# add the locaton alias
for location_alias in form.location_alias.data.split('*'):
if location_alias:
add_location_alias(l, location_alias)
# get the orientations
orientations = []
for o in form.orientation.data:
orientation = Orientation.query.filter_by(orientation=o).first()
if orientation:
orientations.append(orientation)
# add the user
u = User(
email=form.email.data,
username=form.username.data,
password=form.password.data,
sex=form.sex.data,
min_age=form.min_age.data,
max_age=form.max_age.data,
location_id=l.id,
location_radius=form.location_radius.data,
orientations=orientations,
subreddits=[]
)
db.session.add(u)
db.session.commit()
print 'User has been added successfully.'
return redirect(url_for('main.index'))
print 'Form failed validation.'
return render_template('auth/register.html', form=form)