0

Given a table xyz that I have defined via db.define_table('xyz'..) that I can reference as db.xzy, how can I add a new field to this already defined table object?

The usage case that I'm thinking off is I want to add a created field to several tables. I also want to avoid repeating myself. My thought was to create a function that takes a table and adds the created field to it. So for example:

def addcreated(table):
    # ??? somehow add a new Field('created', 'datetime') to table
    table.created.writable = False
    table._before_insert.append...
    ... etc.

db.define_table('product',
    Field('name','string'),
    Field('weight','double')
)

db.define_table('customer',
    Field('name','string'),
    Field('address','string')
)

addcreated(db.product)
addcreated(db.customer)
User
  • 62,498
  • 72
  • 186
  • 247

2 Answers2

3
created_field = Field('created', 'datetime', writable=False)

db.define_table('product',
    Field('name','string'),
    Field('weight','double'),
    created_field)

or:

db.define_table('product',
    Field('name','string'),
    Field('weight','double'),
    created_field.clone(...))

With .clone() you get a copy of the Field object and can specify a new set of arguments to change some of its attributes.

For re-use of multiple fields, see the documentation on table inheritance.

Anthony
  • 25,466
  • 3
  • 28
  • 57
  • does `clone()` also work with a Table object or only single fields? – User Oct 01 '13 at 19:06
  • `.clone()` is a method of the `Field` class. There is nothing similar for the `Table` class. – Anthony Oct 02 '13 at 02:00
  • Also you can define the fields using `*args`. You could create a list of `Field` objects and do this: `db.define_table('product', *fields)`. – omar Jul 06 '15 at 15:58
2

Maybe you should consider using db._common_fields.append (http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer?#Common-fields-and-multi-tenancy)

For example, if you want to get the creation date of your records, you can add the following lines before your tables definitions :

signature = db.Table(db,'auth_signature',
      Field('created_on','datetime',default=request.now,
            writable=False,readable=False, label=T('Created on')),
        Field('created_by','reference %s' % auth.settings.table_user_name,default=auth.user_id,
            writable=False,readable=False, label=T('Created by'))
      )

db._common_fields.append(signature) #db._common_fields is a list of fields that should belong to all the tables
espern
  • 659
  • 6
  • 14