#python #flask #flask-wtforms #wtforms
#python #flask #колба-wtforms #wtforms
Вопрос:
У меня есть веб-приложение Flask, которое управляет информацией всех киосков. Я создал объект WTForms для информации киоска (forms.py ):
class KioskForm(FlaskForm):
kiosk_name = StringField('Kiosk Name', validators=[DataRequired()])
kiosk_site = SelectField('Kiosk's Site', validators=[DataRequired()])
kiosk_location = StringField(
'Kiosk's Location', validators=[DataRequired()])
kiosk_ip = StringField('IP Address', validators=[
IPAddress(), DataRequired()])
kiosk_mac = StringField('MAC Address', validators=[DataRequired()])
submit = SubmitField('Submit')
def validate_kiosk_name(self, kiosk_name):
kiosk = db.session.query(KioskConf).filter_by(
equipment_name=self.kiosk_name.data).first()
if kiosk is not None:
raise ValidationError('Kiosk Name existed.')
Предположим, я хочу отредактировать информацию о существующем киоске (routes.py ):
@app.route('/edit_kiosk/<kiosk_name>', methods=['GET', 'POST'])
def edit(kiosk_name):
data = db.session.query(KioskConf).filter_by(
equipment_name=kiosk_name).first()
form = KioskForm(kiosk_name=data.equipment_name,
kiosk_location=data.equipment_location,
kiosk_ip=data.equipment_ip,
kiosk_mac=data.equipment_mac)
... ...
Что я хотел сделать, так это: если кто-то изменил название киоска на другое существующее, он будет жаловаться, что название уже существует. Который проверка находится в forms.py .
Но одна проблема заключается в том, что если я отредактировал существующий киоск, возможно, изменил IP-адрес, но имя осталось прежним, после отправки жалобы имя уже существует. Что-то должно быть не так с проверкой имени здесь.
Как заставить WTForms пропустить проверку имени, если имя не изменилось?
Ответ №1:
Я не могу запустить эту логику локально и подтвердить, что она работает, но в прошлом я внедрял решения, подобные этому. Попробуйте это и дайте мне знать, если это вам поможет. Приветствия, -Эндрю
def initializeKioskForm(edit_boolean):
# only validate if edit_boolean is false
if edit_boolean == False:
kiosk = db.session.query(KioskConf).filter_by(
equipment_name=self.kiosk_name.data).first()
if kiosk is not None:
raise ValidationError('Kiosk Name existed.')
class KioskForm(FlaskForm):
kiosk_name = StringField('Kiosk Name', validators=[DataRequired()])
kiosk_site = SelectField('Kiosk's Site', validators=[DataRequired()])
kiosk_location = StringField(
'Kiosk's Location', validators=[DataRequired()])
kiosk_ip = StringField('IP Address', validators=[
IPAddress(), DataRequired()])
kiosk_mac = StringField('MAC Address', validators=[DataRequired()])
submit = SubmitField('Submit')
return KioskForm
from forms import initialize_controller_form
@app.route('/edit_kiosk/<kiosk_name>', methods=['GET', 'POST'])
def edit(kiosk_name):
data = db.session.query(KioskConf).filter_by(
equipment_name=kiosk_name).first()
KioskForm = initializeKioskForm(edit_boolean=True)
form = KioskForm(kiosk_name=data.equipment_name,
kiosk_location=data.equipment_location,
kiosk_ip=data.equipment_ip,
kiosk_mac=data.equipment_mac)
Комментарии:
1. Похоже, что приведенная выше логика заключается в том, чтобы дать разработчику «переключатель», нужно ли формам выполнять проверку или нет при инициализации формы, вместо проверки того, были ли изменены исходные данные поля.
Ответ №2:
Итак, я придумал решение, которое ведет себя именно так, как я хотел, хотя в итоге получилась немного более неуклюжая кодовая база.
В forms.py , добавить инициализатор для хранения исходных данных поля и использовать для сравнения новых данных:
class KioskForm(FlaskForm):
kiosk_name = StringField('Kiosk Name', validators=[DataRequired()])
kiosk_site = SelectField('Kiosk's Site', validators=[DataRequired()])
kiosk_location = StringField(
'Kiosk's Location', validators=[DataRequired()])
kiosk_ip = StringField('IP Address', validators=[
IPAddress(), DataRequired()])
kiosk_mac = StringField('MAC Address', validators=[DataRequired()])
submit = SubmitField('Submit')
# Initialiser
def __init__(self, original_name, *args, **kwargs):
super(KioskForm, self).__init__(*args, **kwargs)
self.original_name = original_name
# Changed to compare the old amp; new data
def validate_kiosk_name(self, kiosk_name):
if kiosk_name.data != self.original_name:
kiosk = db.session.query(KioskConf).filter_by(
equipment_name=self.kiosk_name.data).first()
if kiosk is not None:
raise ValidationError('Kiosk ID existed.')
И в routes.py , введите исходное имя в original_name:
@app.route('/edit_kiosk/<kiosk_name>', methods=['GET', 'POST'])
def edit(kiosk_name):
data = db.session.query(KioskConf).filter_by(
equipment_name=kiosk_name).first()
form = KioskForm(kiosk_name=data.equipment_name,
kiosk_location=data.equipment_location,
kiosk_ip=data.equipment_ip,
kiosk_mac=data.equipment_mac,
original_name=data.equipment_name
)
... ...