如何在wtforms验证中使用来自视图的查询变量函数



情况:

我当前正在尝试验证EditProfile表单。在这方面,我需要能够访问我在位于forms.py中的wtforms中的视图函数中创建的用户变量,以验证名称输入是否与用户的当前值不同,如果不是,则对其运行查询,检查它是否已经在系统中,从而引发验证错误。

代码

路由.py

@bp.route('/edit_user/<name>', methods=['GET', 'POST']) 
@login_required
@group_required(['Master', 'Upper Management', 'Management'])
def edit_user(name):

user = User.query.filter_by(name=name).first()
academy = Academy.query.filter_by(id=user.id).first()
trained = TrainedIn.query.filter_by(teacher=user.id).all()

form = EditProfileForm(obj=user)

if form.validate_on_submit():

if user.name != form.name.data:
new = User.query.filter_by(name=form.name.data).first()
if new is not None:
raise ValidationError('Name already in use.')

if user.phone != form.phone.data:
new = User.query.filter_by(phone=form.phone.data).first()
if new is not None:
raise ValidationError('Phone number already in use.')

if user.email != form.email.data:
new = User.query.filter_by(email=form.email.data).first()
if new is not None:
raise ValidationError('Email already in use.')



return redirect(url_for('edit_user', name=user.name))

elif not form.is_submitted():

form.name.data = user.name
form.phone.data = user.phone
form.email.data = user.email
form.position.data = user.position
form.academy.data = academy.name
form.trained.data = [t.name for t in trained] 

return render_template('edit_user.html', title='Edit User',user=user, form=form)

然而,为了尝试验证,我有这些if语句,但这并没有让我满意,因此我想将它们转移到表单验证中,这是目前的情况。

表单.py

class EditProfileForm(FlaskForm):
name = StringField('Full Name', validators=[DataRequired()])
phone = StringField('Phone Number', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
position = SelectField('Position', validators=[DataRequired()], choices=[
('Upper Management', 'Upper Management'),
('Management', 'Management'), 
('Admin','Admin'), 
('Teacher','Teacher')])
academy = SelectField('Academy', validators=[DataRequired()], choices=[
('Alonso Martínez','Alonso Martínez'),
('Argüelles','Argüelles')
])
trained = SelectMultipleField('Trained to teach', choices=[
('General English', 'General English'),
('Exam', 'Exam'),
('Children', 'Children'),
('Level Test', 'Level Test')
])
submit = SubmitField('Confirm')
def validate_phone(self, phone):
try:
p = phonenumbers.parse(phone.data)
if not phonenumbers.is_valid_number(p):
raise ValueError()
except (phonenumbers.phonenumberutil.NumberParseException, ValueError):
raise ValidationError('Invalid phone number')

我的目标

我的目标是以某种方式将用户变量发送到forms.py,以便能够使用类似于的自定义验证来验证它

def validate_name(self, name):
if name != user.name:
user1 = User.query.filter_by(name=name).first()
if user1 is not None:
raise ValidationError('Name already in use.')

我所做的:

  1. 我已经尝试放置obj=用户,它适用于自动归档值,但不允许我访问该变量
  2. 我试图将用户项目放入烧瓶中的"g"变量中,但是这似乎不起作用,也不是一个好主意考虑到多人使用该应用程序可能会以g结尾同时设置变量

更多信息:

我无法使用flask登录中的current_user变量,因为编辑配置文件的人不是用户,而是权限链上级别更高的人。因此,我认为最好的方法是将已创建的用户变量发送到wtforms以在验证中进行处理。

问题:

所有这一切的主要问题是,我如何将保存了查询的变量从视图发送到表单进行验证,如果这不可能,最好的验证方法是什么,这样用户就可以知道发生了什么,而不会引发内部错误。

答案是将变量发送到表单构造函数,然后从那里将变量设置为表单构造函数的属性。即

路线.py

form = EditProfileForm(obj=user.id)

forms.py

def __init__(self, obj, *args, **kwargs):
self.user = int(obj)
super(EditProfileForm, self).__init__(*args, **kwargs)

最新更新