The "Official" resting place for this slice will be on my JoeCodeswell.WordPress.com blog, here.
I wrote this to turn the web2py book chapter on the Field constructor into working, “fully qualified” examples, so i could understand the meaning and explore the features. There are 2 “fully qualified” examples in mytable for now:
- fulldefaultstrfield – is my cut at fullyqualifying the default settings for the Field constructor named parameters.
- fullplay1strfield – is my 1st cut at playing around with the values of the named parameters in the Field constructor.
The results can be seen by implementing this locally and navigating to:
- inserting new records at http://127.0.0.1:8000/fields/appadmin/select/db
- seeing the table grid at http://127.0.0.1:8000/fields/default/gridmytable
Content
- In applications/fields/controllers/default.py
- In applications/fields/models/db.py
In applications/fields/controllers/default.py
# -*- coding: utf-8 -*- # In applications/fields/controllers/default.py def gridmytable(): grid = SQLFORM.grid(db.mytable) return locals()
In applications/fields/models/db.py
# -*- coding: utf-8 -*- # In applications/fields/models/db.py # web2py Field Exegesis # Joe Dorocak aka Joe Codeswell has written working Python code examples exploring "fully qualified" web2py Field constructors. # I wrote this to turn the web2py book chapter on the Field constructor into working, "fully qualified" examples, so i could understand the meaning and explore the features. There are 2 "fully qualified" examples in mytable for now. # - fulldefaultstrfield - is my cut at fullyqualifying the default settings for the Field constructor named parameters. # - fullplay1strfield - is my 1st cut at playing around with the values of the named parameters in the Field constructor. # The results can be seen by implementing this locally and navigating to # - inserting new records at http://127.0.0.1:8000/fields/appadmin/select/db # - seeing the table grid at http://127.0.0.1:8000/fields/default/gridmytable # BOILERPLATE if not request.env.web2py_runtime_gae: db = DAL('sqlite://storage.sqlite',pool_size=1,check_reserved=['all']) else: db = DAL('google:datastore') session.connect(request, response, db=db) response.generic_patterns = ['*'] if request.is_local else [] from gluon.tools import Auth, Crud, Service, PluginManager, prettydate auth = Auth(db) crud, service, plugins = Crud(db), Service(), PluginManager() ## create all tables needed by auth if not custom tables auth.define_tables(username=False, signature=False) # END BOILERPLATE # START HERE db.define_table('mytable', Field('myfield','string'), # see http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Field-constructor # a fully defined field example that will HOPEFULLY work # Not all of the parameters are relevant for every field type. Field( 'fulldefaultstrfield', # Field name positional arg type='string', # Field type see field_types below # Sets the maximum length of a "string", "password" or "upload" field. # See "2.6.1 - 2.6.4" in http://www.web2py.com/init/default/changelog # "MySQL users: The length of string fields changed from 255 to 512 bytes. length=512, default='', # Default value used to pre-populate forms, can instead be a [lambda] function required=False, # True => A val for field MUST be specified at record insertion. requires=IS_LENGTH(512), # Is a validator or a list of validators. see book /forms-and-validators#Validators. see field_types below # joeNote: bad_value == '<DEFAULT>' ondelete='CASCADE', # Defines actions on record delete. CASCADE => delete all referring records notnull=False, # True => fulldeffield can't be Null at record insertion. unique=False, # True => must be unique in the table [not quite the same as IS_NOT_IN_DB] uploadfield=True, # Applies only to fields of type "upload" [Even though True is default and works for type=='string']. See upload_field_type_notes below # Must be one of the available widget objects, including custom widgets. # Each field type has a default widget. See widgetList below # This is default for fulldeffield.type=='string' widget=SQLFORM.widgets.string.widget, label=None, # Is a string (or a helper or something that can be serialized to a string) that contains the label to be used for this field in auto-generated forms. # JoeNote: There's a diff between label=None => default label & label='' => NO LABEL SHOWN! comment='', # Is a string (or a helper or something that can be serialized to a string) that contains a comment associated with this field, and will be displayed to the right of the input field in the autogenerated forms. # JoeNote: No diff between comment='' & comment=None # If a field is neither readable nor writable, it will not be displayed in create and update forms. writable=True, # Declares whether a field is writable in forms. readable=True, # Declares whether a field is readable in forms. update=None, # Contains the default value for this field when the record is updated. authorize=None, # For "upload" fields only, can be used to require access control on the corresponding field. See Authentication and also Authorization http://web2py.com/books/default/chapter/29/09/access-control. autodelete=False, # For "upload" fields only, determines if the corresponding uploaded file should be deleted when the record referencing the file is deleted. represent=None, # Can be None or can point to a function that takes a field value and returns an alternate representation for the field value. See representation_examples below. compute=None, # See compute_notes below. uploadfolder=None, # See upload_field_type_notes below uploadseparate=None, # See upload_field_type_notes below uploadfs=None # See upload_field_type_notes below ), # joe says do a diff on following & above to hilight what changed # i think i changed: fieldname, length, requires, label, comment, represent # need to provide insert & rendering actions to see diffs in result # see http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Field-constructor # a fully defined field example that will HOPEFULLY work # Not all of the parameters are relevant for every field type. Field( 'fullplay1strfield', # Field name positional arg type='string', # Field type see field_types below # Sets the maximum length of a "string", "password" or "upload" field. # See "2.6.1 - 2.6.4" in http://www.web2py.com/init/default/changelog # "MySQL users: The length of string fields changed from 255 to 512 bytes. length=4096, default='', # Default value used to pre-populate forms, can instead be a [lambda] function required=False, # True => A val for field MUST be specified at record insertion. requires=IS_LENGTH(4096), # Is a validator or a list of validators. see book /forms-and-validators#Validators. see field_types below # joeNote: bad_value == '<DEFAULT>' ondelete='CASCADE', # Defines actions on record delete. CASCADE => delete all referring records notnull=False, # True => fulldeffield can't be Null at record insertion. unique=False, # True => must be unique in the table [not quite the same as IS_NOT_IN_DB] uploadfield=True, # Applies only to fields of type "upload" [Even though True is default and works for type=='string']. See upload_field_type_notes below # Must be one of the available widget objects, including custom widgets. # Each field type has a default widget. See widgetList below # This is default for fulldeffield.type=='string' widget=SQLFORM.widgets.string.widget, label='lblPlay1strfield', # Is a string (or a helper or something that can be serialized to a string) that contains the label to be used for this field in auto-generated forms. # JoeNote: There's a diff between label=None => default label & label='' => NO LABEL SHOWN! comment='cmtPlay1strfield', # Is a string (or a helper or something that can be serialized to a string) that contains a comment associated with this field, and will be displayed to the right of the input field in the autogenerated forms. # JoeNote: No diff between comment='' & comment=None # If a field is neither readable nor writable, it will not be displayed in create and update forms. writable=True, # Declares whether a field is writable in forms. readable=True, # Declares whether a field is readable in forms. update=None, # Contains the default value for this field when the record is updated. authorize=None, # For "upload" fields only, can be used to require access control on the corresponding field. See Authentication and also Authorization http://web2py.com/books/default/chapter/29/09/access-control. autodelete=False, # For "upload" fields only, determines if the corresponding uploaded file should be deleted when the record referencing the file is deleted. # Can be None or can point to a function that takes a field value and returns an alternate representation for the field value. See representation_examples below. # represent=lambda fullplay1strfield,row: fullplay1strfield.capitalize(), # result ticket: File "C:/web2py/applications/fields/models/db.py", line 194, in <lambda> # represent=lambda fullplay1strfield,row: fullplay1strfield.capitalize(), # AttributeError: 'NoneType' object has no attribute 'capitalize' # it was None represent=lambda fullplay1strfield,row: fullplay1strfield.capitalize(), compute=None, # See compute_notes below. uploadfolder=None, # See upload_field_type_notes below uploadseparate=None, # See upload_field_type_notes below uploadfs=None # See upload_field_type_notes below ), ) # see http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Field-types field_types = ''' field_type default_field_validators string IS_LENGTH(length) default length is 512 text IS_LENGTH(65536) blob None boolean None integer IS_INT_IN_RANGE(-1e100, 1e100) double IS_FLOAT_IN_RANGE(-1e100, 1e100) decimal(n,m) IS_DECIMAL_IN_RANGE(-1e100, 1e100) date IS_DATE() time IS_TIME() datetime IS_DATETIME() password None upload None reference <table> IS_IN_DB(db,table.field,format) list:string None list:integer None list:reference <table> IS_IN_DB(db,table.field,format,multiple=True) json IS_JSON() bigint None big-id None big-reference None ''' upload_field_type_notes = ''' uploadfield: applies only to fields of type "upload". A field of type "upload" stores the name of a file saved somewhere else, by default on the filesystem under the application "uploads/" folder. If uploadfield is set to True, then the file is stored in a blob field within the same table and the value of uploadfield is the name of the blob field. This will be discussed in more detail later in the context of SQLFORM. uploadfolder: defaults to the application's "uploads/" folder. If set to a different path, files will uploaded to a different folder. For example, Field(...,uploadfolder=os.path.join(request.folder,'static/temp')) will upload files to the "web2py/applications/myapp/static/temp" folder. uploadseparate: if set to True will upload files under different subfolders of the uploadfolder folder. This is optimized to avoid too many files under the same folder/subfolder. ATTENTION: You cannot change the value of uploadseparate from True to False without breaking links to existing uploads. web2py either uses the separate subfolders or it does not. Changing the behavior after files have been uploaded will prevent web2py from being able to retrieve those files. If this happens it is possible to move files and fix the problem but this is not described here. uploadfs: allows you specify a different file system where to upload files, including an Amazon S3 storage or a remote SFTP storage. This option requires PyFileSystem installed. uploadfs must point to PyFileSystem. uploadfs ''' widgetList = [ # See http://web2py.com/books/default/chapter/29/07/forms-and-validators?search=widgets#Widgets # Here is a list of available web2py widgets: SQLFORM.widgets.string.widget, # default for corresonding type SQLFORM.widgets.text.widget, # default for corresonding type SQLFORM.widgets.password.widget, # default for corresonding type SQLFORM.widgets.integer.widget, # default for corresonding type SQLFORM.widgets.double.widget, # default for corresonding type SQLFORM.widgets.time.widget, # default for corresonding type SQLFORM.widgets.date.widget, # default for corresonding type SQLFORM.widgets.datetime.widget, # default for corresonding type SQLFORM.widgets.upload.widget, # default for corresonding type SQLFORM.widgets.boolean.widget, # default for corresonding type # The next 2 widgets are used when a field's requires is IS_IN_SET or IS_IN_DB # The "options" widget is used with multiple=False (default behavior), when a field's requires is IS_IN_SET or IS_IN_DB. SQLFORM.widgets.options.widget, # The "multiple" widget is used with multiple=True, when a field's requires is IS_IN_SET or IS_IN_DB. SQLFORM.widgets.multiple.widget, # The "radio" and "checkboxes" widgets are never used by default, but can be set manually. SQLFORM.widgets.radio.widget, SQLFORM.widgets.checkboxes.widget, # See http://web2py.com/books/default/chapter/29/07/forms-and-validators?search=widgets#Autocomplete-widget SQLFORM.widgets.autocomplete, ] representation_examples = ''' db.mytable.name.represent = lambda name,row: name.capitalize() db.mytable.other_id.represent = lambda id,row: row.myfield db.mytable.some_uploadfield.represent = lambda value,row: A('get it', _href=URL('download', args=value)) "blob" fields are also special. By default, binary data is encoded in base64 before being stored into the actual database field, and it is decoded when extracted. This has the negative effect of using 25% more storage space than necessary in blob fields, but has two advantages. On average it reduces the amount of data communicated between web2py and the database server, and it makes the communication independent of back-end-specific escaping conventions. ''' compute_notes = ''' from http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Computed-fields Computed fields DAL fields may have a compute attribute. This must be a function (or lambda) that takes a Row object and returns a value for the field. When a new record is modified, including both insertions and updates, if a value for the field is not provided, web2py tries to compute from the other field values using the compute function. Here is an example: >>> db.define_table('item', Field('unit_price','double'), Field('quantity','integer'), Field('total_price', compute=lambda r: r['unit_price']*r['quantity'])) >>> r = db.item.insert(unit_price=1.99, quantity=5) >>> print r.total_price 9.95 Notice that the computed value is stored in the db and it is not computed on retrieval, as in the case of virtual fields, described later. Two typical applications of computed fields are: in wiki applications, to store the processed input wiki text as HTML, to avoid re-processing on every request for searching, to compute normalized values for a field, to be used for searching. Computed fields are evaluated in the order in which they are defined in the table definition. A computed field can refer to previously defined computed fields (new after v 2.5.1) Virtual fields Virtual fields are also computed fields ... see: http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Virtual-fields ''' grid_notes = ''' SQLFORM.grid signature http://web2py.com/books/default/chapter/29/07/forms-and-validators#SQLFORM-grid-signature The complete signature for the grid is the following: SQLFORM.grid( query, fields=None, field_id=None, left=None, headers={}, orderby=None, groupby=None, searchable=True, sortable=True, paginate=20, deletable=True, editable=True, details=True, selectable=None, create=True, csv=True, links=None, links_in_grid=True, upload='<default>', args=[], user_signature=True, maxtextlengths={}, maxtextlength=20, onvalidation=None, oncreate=None, onupdate=None, ondelete=None, sorter_icons=(XML('↑'), XML('↓')), ui = 'web2py', showbuttontext=True, _class="web2py_grid", formname='web2py_grid', search_widget='default', ignore_rw = False, formstyle = 'table3cols', exportclasses = None, formargs={}, createargs={}, editargs={}, viewargs={}, buttons_placement = 'right', links_placement = 'right' ) ... JoeNite: below => see SQLFORM http://web2py.com/books/default/chapter/29/07/forms-and-validators#SQLFORM http://web2py.com/books/default/chapter/29/07/forms-and-validators#SQLFORM-and-insert-update-delete google: SQLFORM for select https://groups.google.com/forum/#!topic/web2py/VKvw3Mn-mNQ Because the edit/create form is an SQLFORM which extends FORM, these callbacks are essentially used in the same way as documented in the sections for FORM and SQLFORM. Here is skeleton code: def myonvalidation(form): print "In onvalidation callback" print form.vars form.errors= True #this prevents the submission from completing #...or to add messages to specific elements on the form form.errors.first_name = "Do not name your child after prominent deities" form.errors.last_name = "Last names must start with a letter" response.flash = "I don't like your submission" def myoncreate(form): print 'create!' print form.vars def myonupdate(form): print 'update!' print form.vars def myondelete(table, id): print 'delete!' print table, id onupdate and oncreate are the same callbacks available to SQLFORM.process() '''
Comments (0)