FINALLY!
Thank you Anthony...
Now works perfectly...
With this syntax :
db.ref_tregistry.fnaregistry_id.requires =\
[IS_EMPTY_OR(IS_IN_DB(db,'table.field1')),
ONLY_ONE_CAN_BE_FILLED([request.vars.field2],error_message='Select a
volume or an folder')]
It was drive me nuts to rewrite the IS_IN_DB to include my
ONLY_ONE_CAN_BE_FILLED() validator... I was thinking hmm... What will I have
to do with all the other validator... ;-)
Regards
Richard
On Wed, Jun 22, 2011 at 4:38 PM, Anthony <[email protected]> wrote:
> 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<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([**reque**st.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
>>>>>>
>>>>>>
>>>>>>
>>>>
>>>
>>