Skip to content

Instantly share code, notes, and snippets.

@mdellavo
Created December 3, 2011 16:53
Show Gist options
  • Save mdellavo/1427550 to your computer and use it in GitHub Desktop.
Save mdellavo/1427550 to your computer and use it in GitHub Desktop.
Formencode validators to validate the existence if records in a database
from formencode import validators, Schema
# FIXME - these are the new versions
class RecordExists(FancyValidator):
messages = {'not_found': 'No such record exists'}
def __init__(self, model, field=None, *args, **kwargs):
super(RecordExists, self).__init__(*args, **kwargs)
self.model = model
self.field = field
def _to_python(self, value, state):
obj = self.finder(value, state)
if not obj:
raise Invalid(self.message('not_found', state), value, state)
return obj
def finder(self, value, state):
query = Session.query(self.model)
if self.field:
return query.filter(self.field == value).first()
else:
return query.get(value)
# FIXME probably should subclass after all and override finder
class UniqueField(FancyValidator):
messages = {'found': 'A record already exists with this value'}
def __init__(self, model, field, *args, **kwargs):
super(UniqueField, self).__init__(*args, **kwargs)
self.model = model
self.field = field
def finder(self, query, value, state):
extra_clause = getattr(state, 'extra_clause', None)
if extra_clause:
query = query.filter(extra_clause)
return query
def _to_python(self, value, state):
query = Session.query(self.model).filter(self.field == value)
query = self.finder(query, value, state)
if query.count() > 0:
raise Invalid(self.message('found', state), value, state)
return value
class ObjectDoesNotExistValidator(validators.FancyValidator):
'''
Verifies that no objects are found matching key in model
'''
model = None
key = None
entity = 'record'
messages = {
'no_model' : 'You must specify a model to run',
'empty' : 'Please enter a value',
'found' : '%(entity)s found matching "%(value)s"'
}
def _to_python(self, value, state):
if self.model is None:
raise Invalid(self.message('no_model', state), value, state)
if self.not_empty and value is None:
raise Invalid(self.messag('empty', state), value, state)
if self.key is None:
rv = state.session.query(self.model).get(value)
if rv is not None:
raise Invalid(self.message('found', state, entity=self.entity, value=value), value, state)
else:
if state.session.query(self.model).filter_by(**{self.key: value}).first() is not None:
raise Invalid(self.message('found', state, entity=self.entity, value=value), value, state)
class ObjectExistsValidator(validators.FancyValidator):
'''
Verifies that a record is found matching key by executing given query
'''
model = None
key = None
entity = 'record'
messages = {
'no_model' : 'You must specify a model to run',
'empty' : 'Please enter a value',
'not_found' : 'No %(entity)s found matching "%(value)s"',
'too_many' : 'More than one %(entity)s found matching "%(value)s"'
}
def _to_python(self, value, state):
if self.model is None:
raise Invalid(self.message('no_model', state), value, state)
if self.not_empty and value is None:
raise Invalid(self.messag('empty', state), value, state)
if self.key is None:
rv = state.session.query(self.model).get(value)
if rv is None:
raise Invalid(self.message('not_found', state, entity=self.entity, value=value), value, state)
else:
try:
rv = state.session.query(self.model).filter_by(**{self.key: value}).one()
except NoResultFound, e:
raise Invalid(self.message('not_found', state, entity=self.entity, value=value), value, state)
except MultipleResultsFound, e:
raise Invalid(self.message('too_many', state, entity=self.entity, value=value), value, state)
return rv
# Example
class FooForm(Schema):
foo = ObjectExistsValidator(not_empty=True, model=Foo)
class FooController(BaseController):
@restrict('POST')
@validate(schema=FooForm(), form='new', variable_decode=True, state=DumbObject(session=meta.Session))
def update(self):
pass # self.form_result['foo'] is Foo object with given primary key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment