Flask WTForms - 基于多个表单字段的自定义验证器
Flask WTForms - Custom validators based of multiple form fields
我有一本书 table,其中有大量可用的书籍,我有借书 table,我在其中输入借书和数量。
我正在尝试为我的表单创建自定义验证器功能,如果为借书输入的数量高于图书中的可用数量,该功能将在表单中显示错误消息 table。
这是型号:
class Borrow(db.Model):
"""
Create a Books table
"""
__tablename__ = 'borrows'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), index=True)
quantity_borrow = db.Column(db.Integer)
date_borrow = db.Column(db.DATE)
employees_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
book_id = db.Column(db.Integer, db.ForeignKey('books.id'))
def __repr__(self):
return '<Borrow: {}>'.format(self.name)
class Book(db.Model):
"""
Create a Books table
"""
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key=True)
book_name = db.Column(db.String(60), index=True,unique=True)
author = db.Column(db.String(200), index=True)
quantity = db.Column(db.Integer)
department_id = db.Column(db.Integer, db.ForeignKey('departments.id'))
employees_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
publisher = db.Column(db.String(200))
no_of_pgs = db.Column(db.Integer)
pbs_year = db.Column(db.Integer)
genre_id = db.Column(db.Integer, db.ForeignKey('genres.id'), nullable=False)
read = db.Column(db.Enum('NO', 'YES'), default='NO')
borrows = db.relationship('Borrow', backref='book',
lazy='dynamic')
这是观点:
@admin_role.route('/books/add', methods=['GET', 'POST'])
@login_required
def add_book():
"""
Add a book to the database
"""
check_admin_role()
add_book = True
form = BookForm()
if form.validate_on_submit():
book = Book(book_name=form.book_name.data,
author=form.author.data,
quantity=form.quantity.data,
department_id=form.department_name.data,
employees_id=current_user.id,
publisher=form.publisher.data,
no_of_pgs=form.no_of_pgs.data,
pbs_year=form.pbs_year.data,
genre_id=form.genre_name.data,
read=form.read.data)
try:
# add department to the database
db.session.add(book)
db.session.commit()
flash('You have successfully added a new department.')
except:
# in case department name already exists
flash('Error: Book name already exists.')
# redirect to departments page
return redirect(url_for('admin_role.list_books'))
# load department template
return render_template('books/book.html', action="Add",
add_book=add_book, form=form,
title="Add Book", page="books")
@admin_role.route('/borrows/add', methods=['GET', 'POST'])
@login_required
def add_borrow():
"""
Add a borrow to the database
"""
check_admin_role()
add_borrow = True
form = BorrowForm()
if form.validate_on_submit():
borrow = Borrow(name=form.name.data,
book_id=form.book_name.data,
quantity_borrow=form.quantity_borrow.data,
date_borrow=form.date_borrow.data)
# add department to the database
db.session.add(borrow)
db.session.commit()
flash('You have successfully added a new borrow.')
# redirect to borrows page
return redirect(url_for('admin_role.list_borrows'))
# load department template
return render_template('borrows/borrow.html', action="Add",
add_borrow=add_borrow, form=form,
title="Add Borrow", page="borrows")
这是表格
class BookForm(FlaskForm):
"""
Form for admin_role to add or edit a books
"""
book_name = StringField('Book Name', validators=[DataRequired()])
author = StringField('Author', validators=[DataRequired()])
genre_name = SelectField(coerce=int, validators=[DataRequired()])
quantity = IntegerField('Quantity', validators=[DataRequired()])
department_name = SelectField(coerce=int, validators=[DataRequired()])
publisher = StringField('Publisher', validators=[DataRequired()])
no_of_pgs = IntegerField('Number of pages', validators=[DataRequired()])
pbs_year = IntegerField('Publishing Year', validators=[DataRequired()])
read = SelectField("Read", choices=[(e, e) for e in Book.read.property.columns[0].type.enums])
submit = SubmitField('Submit')
def __init__(self):
super(BookForm, self).__init__()
self.department_name.choices = [(c.id, c.name) for c in Department.query.all()]
self.genre_name.choices = [(g.id, g.name) for g in Genre.query.all()]
class BorrowForm(FlaskForm):
"""
Form for admin_role to add or edit a books
"""
name = StringField('Borrower Name', validators=[DataRequired()])
book_name = SelectField(coerce=int, validators=[DataRequired()])
quantity_borrow = IntegerField('Quantity Borrow', validators=[DataRequired())
date_borrow = DateField('Borrow Date', validators=[DataRequired()])
submit = SubmitField('Submit')
def __init__(self):
super(BorrowForm, self).__init__()
self.book_name.choices = [(c.id, c.book_name) for c in Book.query.all()]
在 wtforms 中,您可以通过在该表单下编写方法来验证字段 class。
在该方法中,validate_
前缀调用以其命名的字段。 self
参数将是 BorrowForm
class 本身,而 field
参数将是您使用 validate_
调用的字段
class BorrowForm(FlaskForm):
...
def validate_quantity_borrow(self, field):
if field.data > (Book.query.filter_by(id=self.book_name.data).first().quantity - sum(i.quantity_borrow for i in Borrow.query.filter_by(book_id=self.book_name.data).all()):
raise ValidationError("More than we have")
field
这里是你的 BorrowForm
的 quantity_borrow
属性。提交后,您需要获取其数据,因此 field.data
会为您提供输入的数量。之后,您将通过使用 book_id
作为 self.book_name.data
过滤数据库来选择这本书,这为您提供了 self
作为 BorrowForm
class 本身和 book_name
属性然后,该属性的 data
是所选书籍的 ID。
你需要导入你的数据库模型,比如在你的 forms.py 文件中,你还需要导入 ValidationError
:
from wtforms.validators import ValidationError
我有一本书 table,其中有大量可用的书籍,我有借书 table,我在其中输入借书和数量。
我正在尝试为我的表单创建自定义验证器功能,如果为借书输入的数量高于图书中的可用数量,该功能将在表单中显示错误消息 table。
这是型号:
class Borrow(db.Model):
"""
Create a Books table
"""
__tablename__ = 'borrows'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), index=True)
quantity_borrow = db.Column(db.Integer)
date_borrow = db.Column(db.DATE)
employees_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
book_id = db.Column(db.Integer, db.ForeignKey('books.id'))
def __repr__(self):
return '<Borrow: {}>'.format(self.name)
class Book(db.Model):
"""
Create a Books table
"""
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key=True)
book_name = db.Column(db.String(60), index=True,unique=True)
author = db.Column(db.String(200), index=True)
quantity = db.Column(db.Integer)
department_id = db.Column(db.Integer, db.ForeignKey('departments.id'))
employees_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
publisher = db.Column(db.String(200))
no_of_pgs = db.Column(db.Integer)
pbs_year = db.Column(db.Integer)
genre_id = db.Column(db.Integer, db.ForeignKey('genres.id'), nullable=False)
read = db.Column(db.Enum('NO', 'YES'), default='NO')
borrows = db.relationship('Borrow', backref='book',
lazy='dynamic')
这是观点:
@admin_role.route('/books/add', methods=['GET', 'POST'])
@login_required
def add_book():
"""
Add a book to the database
"""
check_admin_role()
add_book = True
form = BookForm()
if form.validate_on_submit():
book = Book(book_name=form.book_name.data,
author=form.author.data,
quantity=form.quantity.data,
department_id=form.department_name.data,
employees_id=current_user.id,
publisher=form.publisher.data,
no_of_pgs=form.no_of_pgs.data,
pbs_year=form.pbs_year.data,
genre_id=form.genre_name.data,
read=form.read.data)
try:
# add department to the database
db.session.add(book)
db.session.commit()
flash('You have successfully added a new department.')
except:
# in case department name already exists
flash('Error: Book name already exists.')
# redirect to departments page
return redirect(url_for('admin_role.list_books'))
# load department template
return render_template('books/book.html', action="Add",
add_book=add_book, form=form,
title="Add Book", page="books")
@admin_role.route('/borrows/add', methods=['GET', 'POST'])
@login_required
def add_borrow():
"""
Add a borrow to the database
"""
check_admin_role()
add_borrow = True
form = BorrowForm()
if form.validate_on_submit():
borrow = Borrow(name=form.name.data,
book_id=form.book_name.data,
quantity_borrow=form.quantity_borrow.data,
date_borrow=form.date_borrow.data)
# add department to the database
db.session.add(borrow)
db.session.commit()
flash('You have successfully added a new borrow.')
# redirect to borrows page
return redirect(url_for('admin_role.list_borrows'))
# load department template
return render_template('borrows/borrow.html', action="Add",
add_borrow=add_borrow, form=form,
title="Add Borrow", page="borrows")
这是表格
class BookForm(FlaskForm):
"""
Form for admin_role to add or edit a books
"""
book_name = StringField('Book Name', validators=[DataRequired()])
author = StringField('Author', validators=[DataRequired()])
genre_name = SelectField(coerce=int, validators=[DataRequired()])
quantity = IntegerField('Quantity', validators=[DataRequired()])
department_name = SelectField(coerce=int, validators=[DataRequired()])
publisher = StringField('Publisher', validators=[DataRequired()])
no_of_pgs = IntegerField('Number of pages', validators=[DataRequired()])
pbs_year = IntegerField('Publishing Year', validators=[DataRequired()])
read = SelectField("Read", choices=[(e, e) for e in Book.read.property.columns[0].type.enums])
submit = SubmitField('Submit')
def __init__(self):
super(BookForm, self).__init__()
self.department_name.choices = [(c.id, c.name) for c in Department.query.all()]
self.genre_name.choices = [(g.id, g.name) for g in Genre.query.all()]
class BorrowForm(FlaskForm):
"""
Form for admin_role to add or edit a books
"""
name = StringField('Borrower Name', validators=[DataRequired()])
book_name = SelectField(coerce=int, validators=[DataRequired()])
quantity_borrow = IntegerField('Quantity Borrow', validators=[DataRequired())
date_borrow = DateField('Borrow Date', validators=[DataRequired()])
submit = SubmitField('Submit')
def __init__(self):
super(BorrowForm, self).__init__()
self.book_name.choices = [(c.id, c.book_name) for c in Book.query.all()]
在 wtforms 中,您可以通过在该表单下编写方法来验证字段 class。
在该方法中,validate_
前缀调用以其命名的字段。 self
参数将是 BorrowForm
class 本身,而 field
参数将是您使用 validate_
class BorrowForm(FlaskForm):
...
def validate_quantity_borrow(self, field):
if field.data > (Book.query.filter_by(id=self.book_name.data).first().quantity - sum(i.quantity_borrow for i in Borrow.query.filter_by(book_id=self.book_name.data).all()):
raise ValidationError("More than we have")
field
这里是你的 BorrowForm
的 quantity_borrow
属性。提交后,您需要获取其数据,因此 field.data
会为您提供输入的数量。之后,您将通过使用 book_id
作为 self.book_name.data
过滤数据库来选择这本书,这为您提供了 self
作为 BorrowForm
class 本身和 book_name
属性然后,该属性的 data
是所选书籍的 ID。
你需要导入你的数据库模型,比如在你的 forms.py 文件中,你还需要导入 ValidationError
:
from wtforms.validators import ValidationError