Actually, I borrowed Anthony's excellent idea and made a "factory" class for my field definitions.
First I defined a factory class: class Field_Factory(object): from gluon import Field @staticmethod def new(**kwargs): default = dict(**kwargs) def inner(name, **kwargs): args = dict(default) args.update(**kwargs) if args.pop('hidden',False): args.update(dict(readable=False,writable=False)) req = args.get('requires', None) if req and (args.get('represent',None)=='formatter'): args['represent'] = req.formatter if args.pop('optional',False) and req: args['requires'] = IS_EMPTY_OR(req) rend = args.pop('render',None) rtn = Field(name, **args) if rend: rtn.render = rend return rtn return inner factory = Field_Factory() Then I used it to create a bunch of field generators: phone_field = factory.new( type='string', length=20, requires=IS_PHONE(), optional=True, widget=lambda fld,val: SQLFORM.widgets.string.widget( fld, val, _type='tel', _class='form-control') ) email_field = factory.new( type='string', length=50, requires=IS_EMAIL(), optional=True, widget=lambda fld,val: SQLFORM.widgets.string.widget( fld, val, _type='email', _class='form-control') ) date_field = factory.new( type='date', requires=IS_DATE(format='%m-%d-%Y'), optional=True, represent=lambda v,r: v.strftime('%m-%d-%Y'), widget=lambda fld,val:SQLFORM.widgets.date.widget( fld, val, _class="date form-control") ) datetime_field = factory.new( type='datetime', requires=IS_DATETIME(format='%m-%d-%Y %I:%M:%S %p'), optional=True, represent=lambda v,r: v.strftime('%m-%d-%Y %I:%M:%S %p'), widget=lambda fld,val: SQLFORM.widgets.datetime.widget( fld, val, _class="datetime form-control") ) zipcode_field = factory.new( type='string', length=10, requires=IS_ZIPCODE(), widget=lambda fld,val: SQLFORM.widgets.string.widget( fld, val, _type="zip", _class='zipcode form-control') ) Finally, when I use the field generators in any table definitions, I can further customize them and the changes are passed through. define_table('joes_table', . . . date_field("birth", label=T("Birth date")), . . . It all works really well and gives me the single point of control I want. It requires no changes in web2py and works with current, past, and future versions. And the lazy programmer in me marvels at all the code I don't have to type. -- Joe On Thursday, March 23, 2017 at 12:54:58 PM UTC-7, Joe Barnhart wrote: > > Here is a bit of syntactic sugar I use for creating fields with less > typing. And better consistency, of course -- there always has to be a good > reason for my lazy keyboard-saving shortcuts! > > I have a number of fields which are for specific data types, such as phone > numbers. I gather the "common" parts of the Field definition into a > dictionary: > > phone_fld = {'requires':IS_EMPTY_OR(IS_PHONE()), > 'widget':lambda fld,val: SQLFORM.widgets.string.widget(fld, > val,_type='tel',_class='form-control')} > > When defining the field in a table, I invoke the dictionary at the end of > the Field definition: > > Field("homephone","string",length=20,label=T("Home phone"),**phone_fld), > Field("workphone","string",length=20,label=T("Work phone"),**phone_fld), > Field("cellphone","string",length=20,label=T("Cell phone"),**phone_fld), > > Now the field is created exactly as I want. I keep a list of these > "helpers" in a module which I can call out when creating tables. It really > saves the typing and allow me to control how my fields are rendered on one > place instead of scattered among all the tables. > > -- Joe > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.