Details are used in the framework to work with tabular data, pertaining to a record in an item’s table.

For example, the Invoices journal in the Demo application has the InvoiceTable detail, which keeps a list of tracks in an customer’s invoice.

Details and detail items share the same underlying database table.

To create a detail, you must first create a detail item (select Details group of the project tree and click on New button) and then use the Details Dialog (select item in the project tree and click on Details button) to add a detail to an item.

For example the following code

def on_created(task):
    print  task.invoice_table.record_count()
    print task.invoices.invoice_table.record_count()

will print:


Details have two common fields - master_id and master_rec_id, that are used to store information about the ID of the master (each item have its own unique ID) and the value of the primary field of the record of its master. This way each table can be linked to several items. As well as each item can have several details. To get access to details of an item use its details attribute. To get access to the master of the detail use its master attribute.

Detail class, used to create details, is an ancestor of the Item class and inherits all its attributes, methods and events.


The apply method of the Detail class does nothing. To write changes made to a detail use apply method of its master.

To work with a detail its muster must be active

To make any changes to a detail its master must be in an edit or insert mode


In this example from the client module of the Invoices item of Demo project, the Invoice_table detail is reopened every time the cursor of its master moves to another record.

var ScrollTimeOut;

function on_after_scroll(item) {
    ScrollTimeOut = setTimeout(
        function() {

And just as an example:

from datetime import datetime, timedelta

def on_created(task):
    invoices = task.invoices.copy()
    for i in invoices:
        for t in i.invoice_table:
            t.sales_id.value = '101010'

The same code on the client will be as follows:

function on_page_loaded(task) {
    var date = new Date(),
        invoices = task.invoices.copy();

    invoices.set_where({invoicedate__gt: date.setDate(date.getDate() - 1)});;
    invoices.each(function(i) {;
        i.invoice_table.each(function(t) {
            t.sales_id.value = '101010';