Usually validators are set once for all in models.
Occasionally, you need to validate a field and the validator depends on the value of another field. This can be done in various ways. It can be done in the model or in the controller.
There is an example validation done in controller but there is no example validation done in model
My table:
db.define_table('config',
   Field('config_name', 'string', length=255, required=True, unique=True),
   Field('convert_option', 'string', length=255,
       requires=IS_IN_SET(CONVERSION, zero=None)),
   Field('config_value', 'string', length=255, required=True),
   Field('default_value', 'string', length=255, required=True))
I want to validate if config_value is greater than default value (for example), but i don't want to do it in SQLFORM or FORM.
or is it a bad idea to put validation that depend on other fields in "model" rather than form?
Thank you
Hadi
Field('field1', 'reference table2')
There is an example validation done in controller but there is no example validation done in model
My table:
db.define_table('config',
   Field('config_name', 'string', length=255, required=True, unique=True),
   Field('convert_option', 'string', length=255,
       requires=IS_IN_SET(CONVERSION, zero=None)),
   Field('config_value', 'string', length=255, required=True),
   Field('default_value', 'string', length=255, required=True))I want to validate if config_value is greater than default value (for example), but i don't want to do it in SQLFORM or FORM.
or is it a bad idea to put validation that depend on other fields in "model" rather than form?
Field('config_value', ...,
   requires=IS_EXPR(lambda value: value > int(request.post_vars.default_value)))
def index():
  db = DAL('sqlite:memory:')
  db.define_table('department',
    Field('name'), format='%(name)s')
  db.define_table('teacher',
    Field('department_id', 'reference department'),
    Field('name'))
  db.define_table('pupil',
    Field('department_id', 'reference department'),
    Field('teacher_id', 'reference teacher'),
    Field('name'))
  # populating...
  if not db(db.department).count():
    db.department.bulk_insert([dict(id=1, name='Letters'), dict(id=2, name='Numbers')])
  if not db(db.teacher).count():
    db.teacher.bulk_insert([dict(name='TeacherA', department_id=1), dict(name='Teacher1', department_id=2)])
  if not db(db.pupil).count():
    db.pupil.bulk_insert([dict(name='PupilA', department_id=1), dict(name='Pupil1', department_id=2)])
 Â
  db.pupil.teacher_id.requires = IS_EMPTY_OR(IS_IN_DB(db((db.teacher.department_id==db.pupil.department_id)),
                            'teacher.id', '%(name)s', zero=T('Choose one')))
  form = SQLFORM.grid(db.pupil, user_signature=False)
 Â
  return dict(form=form)
(db.teacher.department_id==db.pupil.department_id)
(db.teacher.department_id==request.post_vars.department_id)
  db.pupil.teacher_id.requires = lambda x,row: IS_EMPTY_OR(IS_IN_DB(db((db.teacher.department_id==row.department_id)),
                            'teacher.id', '%(name)s', zero=T('Choose one')))
  if 'edit' in request.args:
    # Ajax department_id -> teacher_id
    # 1.- Initial filter
    form += SCRIPT(''' jQuery(document).ready(function(){
        ajax('%s', ['department_id', 'teacher_id'], 'pupil_teacher_id');
      }); ''' % URL('options_teacher'))
    # 2.- Ajax modification setted by DOM
    department_id = form.element('select #pupil_department_id')
    department_id['_onchange'] = "ajax('%s', ['department_id'], 'pupil_teacher_id')" % URL('options_teacher')
def options_teacher():
  T = db.teacher
  rs = db(T.department_id == request.vars.department_id).select(T.ALL, orderby=T.name)
  teachers = [OPTION(r.name, _value=r.id, _selected=bool(r.id == int(request.vars.teacher_id or 0))) for r in rs]
  return CAT(OPTION(T('Choose One'), _value=''), *teachers)
onvalidation=lambda form: my_onvalidation(form)
  def my_onvalidation(form):
    if form.vars.department_id and form.vars.teacher_id \
    and db.teacher[form.vars.teacher_id].department_id != int(form.vars.department_id):
      form.errors.teacher_id = T('Error')