#python #validation #flask #flask-wtforms #wtforms
#python #проверка #flask #flask-wtforms #wtforms
Вопрос:
Ситуация:
В настоящее время я пытаюсь проверить форму EditProfile. При этом мне нужно иметь доступ к пользовательской переменной, которую я создал в функции просмотра в wtforms, которая находится в forms.py , чтобы проверить, что введенное имя не совпадает с тем, которое является текущим значением для пользователя, и если это не так, то запуститезапросите ее, чтобы проверить, есть ли она уже в системе, чтобы выдать ошибку проверки.
Код
routes.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, чтобы попытаться выполнить проверку, однако, это не работает к моему удовлетворению, поэтому я хочу переместить их в проверку форм, которая выполняется в текущий момент времени.
forms.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.')
Что я сделал:
- Я попытался поместить obj=user, который работает для автоматической подачи значений, но не позволяет мне получить доступ к переменной.
- Я попытался поместить пользовательский элемент в переменную ‘g’ из flask, но это, похоже, не работает и не кажется хорошей идеей, учитывая, что несколько человек, использующих приложение, могут одновременно установить переменную g.
Немного больше информации:
Я не могу использовать переменную current_user из flask-login, поскольку человек, редактирующий профиль, будет не пользователем, а кем-то с более высоким уровнем в цепочке разрешений. Поэтому я считаю, что лучший способ — отправить пользовательскую переменную, которая была создана в wtforms, для обработки при проверке.
Вопрос:
Главный вопрос во всем этом заключается в том, как я могу отправить переменную, в которой сохранен запрос, из представления в форму для проверки, и если это невозможно, каков наилучший способ проверить это таким образом, чтобы пользователь мог знать, что происходит, не просто проверяя, что происходит.выдает внутреннюю ошибку.
Ответ №1:
Ответ состоял в том, чтобы отправить переменную в конструктор формы, а затем оттуда установить переменную в качестве атрибута конструктора формы. т.е.
routes.py
form = EditProfileForm(obj=user.id)
forms.py
def __init__(self, obj, *args, **kwargs):
self.user = int(obj)
super(EditProfileForm, self).__init__(*args, **kwargs)