Here's a potentially better option that will work even in appadmin and doesn't require an extra callback if you need to do an insert followed by an update in the same request:
db.define_table('mytable', Field('modifiable_number', 'integer', requires=IS_NOT_EMPTY()), Field('original', 'integer', readable=False, writable=False)) db.mytable._before_insert = [lambda fields: fields.update(original=fields.get('modifiable_number'))] With the above solution, there is no default or compute attribute. Instead, before an insert (but not before an update), the value of the "original" field is set to match the value of the "modifiable_number" field. Anthony On Sunday, July 10, 2016 at 11:43:22 PM UTC-4, Anthony wrote: > > On Sunday, July 10, 2016 at 4:38:33 PM UTC-4, ahz...@gmail.com wrote: >> >> In my application a user enters a boolean value, and later the user can >> modify the value*.* I want to save the original value in another field, >> and the user shouldn't be able to see or alter the original value. >> >> Based on the stackoverflow >> <http://stackoverflow.com/questions/16280220/setting-the-default-of-a-database-field-to-the-value-of-another-field-in-web2py> >> >> conversation I tried a simple table with two methods >> db.define_table('mytable', >> Field('start_number', 'integer', requires=IS_NOT_EMPTY()), >> Field('n1', 'integer', default=request.post_vars.start_number), >> > > n1 won't work because it is writable and therefore appears in the form, > which means even if you leave it blank, an empty string is submitted as its > value, which SQLFORM converts to a 0 (the default value is inserted only if > no value is submitted). > > Here are two options: > > db.define_table('mytable', > Field('modifiable_number', 'integer', requires=IS_NOT_EMPTY()), > Field('original1', 'integer', readable=False, writable=False, > default=request.post_vars.modifiable_number), > Field('original2', 'integer', readable=False, writable=False, > compute=lambda r: r.modifiable_number)) > > db.mytable._before_update = [lambda t, f: setattr(db.mytable.original2, > 'compute', None)] > > Because original1 is not writable, it will not appear in the form, which > means no value will be submitted for it and therefore its default value > will be inserted. Note, however, that this will not work in appadmin, which > ignores the "writable" attribute and will therefore include original1 in > the insert form. > > original2 will use the computed value only on the initial insert. The > _before_update callback removes the "compute" attribute before any updates, > so no new value will be computed on updates. Note, if you need to do an > insert *after* an update during the *same* HTTP request (which is > probably not a common scenario), you would also need to add an > _after_update callback to restore the "compute" attribute after the update. > > Anthony > -- 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.