How about you just do this somewhere: db.table.field1.widget=SQLFORM.widgets.options.widget or db.define_table('table', Field('field', requires=..., widget=SQLFORM.widgets.options.widget)) Does that bring the drop-down back to your field? Anthony
On Wednesday, June 22, 2011 4:07:22 PM UTC-4, Richard wrote: > I try to hack a bit with IS_IN_DB to include a "ornull=" option that give > this : > > class IS_IN_DB_DEV_ORNULL(): > """ > example:: > > INPUT(_type='text', _name='name', > requires=IS_IN_DB(db, db.mytable.myfield, zero='')) > > used for reference fields, rendered as a dropbox > """ > > def __init__( > self, > dbset, > field, > label=None, > error_message='value not in database', > orderby=None, > groupby=None, > cache=None, > multiple=False, > zero='', > sort=False, > _and=None, > ornull=None, > null=None, > ): > from dal import Table > if isinstance(field,Table): field = field._id > > if hasattr(dbset, 'define_table'): > self.dbset = dbset() > else: > self.dbset = dbset > self.field = field > (ktable, kfield) = str(self.field).split('.') > if not label: > label = '%%(%s)s' % kfield > if isinstance(label,str): > if regex1.match(str(label)): > label = '%%(%s)s' % str(label).split('.')[-1] > ks = regex2.findall(label) > if not kfield in ks: > ks += [kfield] > fields = ks > else: > ks = [kfield] > fields = 'all' > self.fields = fields > self.label = label > self.ktable = ktable > self.kfield = kfield > self.ks = ks > self.error_message = error_message > self.theset = None > self.orderby = orderby > self.groupby = groupby > self.cache = cache > self.multiple = multiple > self.zero = zero > self.sort = sort > self._and = _and > self.ornull = ornull > self.null = null > > def set_self_id(self, id): > if self._and: > self._and.record_id = id > > def build_set(self): > if self.fields == 'all': > fields = [f for f in self.dbset.db[self.ktable]] > else: > fields = [self.dbset.db[self.ktable][k] for k in self.fields] > if self.dbset.db._dbname != 'gae': > orderby = self.orderby or reduce(lambda a,b:a|b,fields) > groupby = self.groupby > dd = dict(orderby=orderby, groupby=groupby, cache=self.cache) > records = self.dbset.select(*fields, **dd) > else: > orderby = self.orderby or reduce(lambda a,b:a|b,(f for f in > fields if not f.name=='id')) > dd = dict(orderby=orderby, cache=self.cache) > records = self.dbset.select(self.dbset.db[self.ktable].ALL, > **dd) > self.theset = [str(r[self.kfield]) for r in records] > if isinstance(self.label,str): > self.labels = [self.label % dict(r) for r in records] > else: > self.labels = [self.label(r) for r in records] > > def options(self): > self.build_set() > items = [(k, self.labels[i]) for (i, k) in enumerate(self.theset)] > if self.sort: > items.sort(options_sorter) > if self.zero != None and not self.multiple: > items.insert(0,('',self.zero)) > return items > > def __call__(self, value): > unused_value, empty = is_empty(value) > """if self.multiple: > if isinstance(value,list): > values=value > elif value: > values = [value] > else: > values = [] > if isinstance(self.multiple,(tuple,list)) and \ > not self.multiple[0]<=len(values)<self.multiple[1]: > return (values, translate(self.error_message)) > if not [x for x in values if not x in self.theset]: > return (values, None) > elif self.theset: > if value in self.theset: > if self._and: > return self._and(value) > else: > return (value, None)""" > if self.ornull: > if self.multiple: > if isinstance(value,list): > values=value > elif value: > values = [value] > else: > values = [] > if isinstance(self.multiple,(tuple,list)) and \ > not self.multiple[0]<=len(values)<self.multiple[1]: > return (values, translate(self.error_message)) > if not [x for x in values if not x in self.theset]: > return (values, None) > elif self.theset: > if value in self.theset: > if self._and: > return self._and(value) > else: > return (value, None) > if empty: > return (self.null, None) > else: > (ktable, kfield) = str(self.field).split('.') > field = self.dbset.db[ktable][kfield] > if self.dbset(field == value).count(): > if self._and: > return self._and(value) > else: > return (value, None) > return (value, translate(self.error_message)) > > > But I am still stock with the NULL in both field that goes trought the > database overriding my ONLY_ONE_CAN_BE_FILLED() validator... > > I also try to add a _and= option to my ONLY_ONE_CAN_BE_FILLED() validator, > but remove the dropbox... > > The only solution that I can see now is to merge IS_IN_DB > with ONLY_ONE_CAN_BE_FILLED() that is not going to be really DRY... > > If someone can see an other solution, I am really open to the idea... > > Richard > > > On Wed, Jun 22, 2011 at 10:31 AM, Richard Vézina <ml.richa...@gmail.com>wrote: > >> Hello Anthony, >> >> The "_and=" works perfectly and bring back the dropbox, but as you >> mention, not all the logic of the validator that I pass in the _and= option >> is working... The IS_EMPTY_OR is overriding the >> >> Here the proper syntax to get the dropbox : >> >> db.table.field1.requires =\ >> IS_EMPTY_OR(IS_IN_DB(db,'table.field1'), >> >> _and=ONLY_ONE_CAN_BE_FILLED([request.vars.field2],error_message='Select only >> one'))) >> >> I try to remove the IS_EMPTY_OR, but as expected the >> IS_IN_DB prevent insertion of a null... >> >> Don't know what the best option to make it works properly... >> >> Adding option to IS_EMPTY_OR() to allow inter independency with >> my ONLY_ONE_CAN_BE_FILLED() or make a _and= option to >> my ONLY_ONE_CAN_BE_FILLED() to make it works with IS_IN_DB?? >> >> Richard >> >> On Tue, Jun 21, 2011 at 9:11 PM, Richard Vézina <ml.richa...@gmail.com>wrote: >> >>> Great thanks Anthony, I will try that tomorrow first time and I will >>> report back. >>> >>> Richard >>> >>> >>> On Tue, Jun 21, 2011 at 5:35 PM, Anthony <abas...@gmail.com> wrote: >>> >>>> When you need to use additional validators with IS_IN_DB but still want >>>> the dropbox, you can add the additional validators to the IS_IN_DB >>>> validator >>>> via its '_and' argument -- see >>>> http://web2py.com/book/default/chapter/07#Database-Validators. However, >>>> I'm not sure if that works when IS_IN_DB is inside an IS_NULL_OR >>>> validator. >>>> (Actually, IS_NULL_OR has been deprecated in favor of IS_EMPTY_OR.) >>>> >>>> Anthony >>>> >>>> On Tuesday, June 21, 2011 5:16:12 PM UTC-4, Richard wrote: >>>> >>>>> Hello, >>>>> >>>>> I would like to know if the problem I face coming from the validator >>>>> that I write or is a IS_IN_DB behavior in case of multiple validators?? >>>>> >>>>> Here my validator : >>>>> >>>>> class ONLY_ONE_CAN_BE_FILLED(object)**: >>>>> """Class representing a validator requiring at least one non-empty >>>>> field in a set. """ >>>>> def __init__( >>>>> self, >>>>> others, >>>>> error_message='Enter a value in at least one field' >>>>> ): >>>>> self.others = others >>>>> self.error_message = error_message >>>>> >>>>> def __call__(self, value): >>>>> okay = (value, None) >>>>> error = (value, self.error_message) >>>>> values = [] >>>>> values.append(value) >>>>> values.extend(self.others) >>>>> empties = [] >>>>> for v in values: >>>>> unused_v, empty = is_empty(v) >>>>> empties.append(empty) >>>>> if empties.count(False) == 1: >>>>> return okay >>>>> else: >>>>> return error >>>>> >>>>> >>>>> But when i use it like this I lost my dropbox for the FK field1 : >>>>> >>>>> db.table.field1.requires =\ >>>>> [IS_NULL_OR(IS_IN_DB(db,'other**table.id <http://othertable.id> >>>>> ','%(fieldrepresent)s'**,orderby=('fieldrepresent'))), >>>>> >>>>> ONLY_ONE_CAN_BE_FILLED([**request.vars.field2],error_**message='Select >>>>> a volume or an folder')] >>>>> >>>>> I remember I read something about IS_IN_DB and [IS_IN_DB]... >>>>> >>>>> Can I have the dropbox and the multiple validators at the same time?? >>>>> >>>>> Thanks >>>>> >>>>> Richard >>>>> >>>>> >>>>> >>> >> >