Created
December 3, 2011 16:53
-
-
Save mdellavo/1427550 to your computer and use it in GitHub Desktop.
Formencode validators to validate the existence if records in a database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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