Checkbox custom form validation for multiple fields?
I intended to create a custom form validation logic based on multiple field values (in my case 2 fields are provided to ensure data integrity of the date range, IE start_time <end_time). However, looking through the documentation on the admin site, I couldn't find anywhere else to do this sort of thing. I know that you can fairly easily pass a list of argument validation functions validators
for a property form_args
in a subclass of the class BaseModelView
, but then again that validation on each field is not exactly what I want.
So my question is this: how can multiple fields be checked at the same time?
Also, I don't see any hook-pre-save event function being used to do this. I know on_model_change
, but then it's a post-save hook, it will defeat the validation target to put the validation in there. What would be the appropriate way to do the preliminary steps?
source to share
So, after experimenting and trying a few different approaches, the way I did multiple validation on a form field is still tied to on_model_change
I know that this suggests that after the changes have been made the event hook is called, however, since it was wrapped in a transaction, any exception can be made to rollback the transaction.
Here is my sample code to make it work.
from flask.ext.admin.form import rules
from wtforms import validators
class TimeWindowView(LoggedInView):
column_filters = ('scheduled_start', 'scheduled_end')
form_create_rules = [
rules.Field('scheduled_start'),
rules.Field('scheduled_end'),
]
def on_model_change(self, form, model, is_created):
# if end date before start date or end date in the past, flag them invalid
if (form.scheduled_end.data <= form.scheduled_start.data or
form.scheduled_end.data <= datetime.datetime.utcnow()):
raise validators.ValidationError('Invalid schedule start and end time!')
else:
super().on_model_change(form, model, is_created)
source to share
You can inject form validation code into the flag model model views by using inheritance and a custom validate_form method that includes your validation code before calling the parent "validation form".
If your validation logic detects a problem, your validate_form should display an appropriate error message and return False, otherwise it should continue by running the source code of the flag addons validation form.
from flask_admin.contrib.sqla import ModelView
from flask import flash
class MyModelView(ModelView):
""" My model admin model view """
def validate_form(self, form):
""" Custom validation code that checks dates """
if form.start_time.data > form.end_time.data:
flash("start time cannot be greater than end time!")
return False
return super(MyModelView, self).validate_form(form)
This is a much more natural place to validate a form than with the change_model_model method, which should not touch the model logic, rather than form the validation logic. Also, please note that we do not need to use an exception and rely on canceling the transaction. We simply catch the error before any transaction has occurred, fire an error message, and gracefully return "False".
Relevant links:
source to share