I have a books table where quantity of books is available and I have borrows table where I enter the borrowed books and quantities.
I am trying to create custom validator function for my form that will show error message in form if quantity entered for borrow book is higher than available quantity in book table.
this is the model:
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')
This is the view:
@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")
And this is the form
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()]
In wtforms you can validate a field by writing a method under that form class.
In this method, validate_
prefix calls the field named after. self
argument will be the BorrowForm
class itself and the field
argument will be the field you called with 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
here is the quantity_borrow
attribute of your BorrowForm
. When submitted you need to get its data so field.data
gives you entered quantity. After that you will get the book chosen by filtering the database with book_id
as self.book_name.data
which gives you, self
as the BorrowForm
class itself and book_name
attribute of it then, the data
of that attribute which is the id of book chosen.
You need to import your database models ,lets say in your forms.py file, and also you need to import ValidationError
:
from wtforms.validators import ValidationError
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加