Using a value of one table as a default value of another table

54 views
Skip to first unread message

mostwanted

unread,
Dec 1, 2018, 2:41:54 PM12/1/18
to web2py-users

I am trying to achieve something here, i have two tables and i want the values of one table to be default values of another table so that i don't have to re enter the same information over & over again: In the code below observe where highlited in green, is there a way for me to do something like below.

CODE:
db.define_table('quotationClient',
               
Field('Client_Surname'),
               
Field('Client_Name'),
               
Field('Company'),
               
Field('Contact_Details'),
               
Field('Book_In', 'date'),
               
Field('Book_Out', 'date'),
               
Field('Days', compute=lambda r: (r['Book_Out']-r['Book_In']).days),
               
Field('Booked_By', 'reference auth_user', default=auth.user_id, writable=False, label=SPAN('Booked In By', _style="font-weight: bold;")),
               
Field('Booking_Date', 'datetime', default=request.now, writable=False, label=SPAN('Booking Date', _style="font-weight: bold;")),
                format
="%(Client_Surname)s %(Client_Name)s"
               
)

db
.define_table('quotation',
               
Field('customer', 'reference quotationClient', writable=False),
               
Field('Quotation_For'),
#HOW CAN I DO THE BELOW IN SUCH A WAY THAT WORKS
             
  Field('Book_In', 'date', default='db.quotationClient.Book_In', writable=False, readable=False),
               
Field('Book_Out', 'date', default='db.quotationClient.Book_Out',  writable=False, readable=False),

               
Field('No_of_Pax', 'integer'),
               
Field('Days', compute=lambda r: (r['Book_Out']-r['Book_In']).days),
               
#Field('No_of_Days', 'integer'),
               
Field('Unit_Price', 'integer'),
               
#Field('vat', compute=lambda r: int(r['Days'])*r['Unit_Price']*r['No_of_Pax']*0.1),
               
Field('Amount', compute=lambda r: int(r['Days'])*r['Unit_Price']* r['No_of_Pax']),
               
Field('Quoted_By','reference auth_user', default=auth.user_id, writable=False),
               
Field('Quoted_On','datetime',default=request.now,writable=False))

Mostwanted

Val K

unread,
Dec 1, 2018, 6:09:43 PM12/1/18
to web2py-users

There are several ways:
0: http://web2py.com/books/default/chapter/29/06/the-database-abstraction-layer#Advanced-features
1: def predefined_field(): return Field(...)  # now,  in any table definition you can just:  db.define_tabel(..., Field(...),  predefined_field(), ...)
2: Also, there is undocumented function : db.any_table.any_field.clone()  - returns copy of the field (decoupled from the table)  + you can pass args to overwrite any fields properties:  db.any_table.any_field.clone(name = 'another_name') 

Anthony

unread,
Dec 1, 2018, 7:01:53 PM12/1/18
to web2py-users
The default argument can be a function, but it does not have access to the other fields being inserted/updated, so it cannot determine the appropriate quotationClient record from which to pull these values. This means you cannot use default for this purpose.

Do you simply want the default values on initial insert to be the values from the quotationClient record, or do you want to keep the values of these fields in sync between quotationClient and quotation?

If the former, I suppose you could make these computed fields -- something like:

Field('Book_In', 'date', compute=lambda r: db.quotationClient(r.customer).Book_In)

Note, that will update the Book_In value on every update in which the customer field is also supplied. Alternatively, you could use a _before_insert() hook to add the Book_In and Book_Out fields before initial insert only.

If you need to keep the fields in sync between the tables, you could use a _before_insert() hook on the quotation table (to grab the initial values), along with an _after_update() hook on the quotationClient table (to update the values in any referencing records).

Anthony
Reply all
Reply to author
Forward
0 new messages