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 <[email protected]>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 <[email protected]>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 <[email protected]> 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
>>>>>
>>>>>
>>>>>
>>>
>>
>