'Pre-populate the form with values from a previous record or
controller-submitted data
@param from_table: the table to copy the data from
@param from_record: the record to copy the data from
@param map_fields: field selection/mapping
@param data: the data to prepopulate the form with
@param format: the request format extension'

def prepopulate(self, from_table=None, from_record=None, map_fields=None, data=None, format=None):

    table = self.table
    record = None
    if (from_table is not None):
        if map_fields:
            if isinstance(map_fields, dict):
                fields = [from_table[map_fields[f]] for f in map_fields if ((f in table.fields) and (map_fields[f] in from_table.fields) and table[f].writable)]
            elif isinstance(map_fields, (list, tuple)):
                fields = [from_table[f] for f in map_fields if ((f in table.fields) and (f in from_table.fields) and table[f].writable)]
            else:
                raise TypeError
        else:
            fields = [from_table[f] for f in table.fields if ((f in from_table.fields) and table[f].writable)]
        (prefix, name) = from_table._tablename.split('_', 1)
        current.audit('read', prefix, name, record=from_record, representation=format)
        query = (from_table.id == from_record)
        row = current.db(query).select(limitby=(0, 1), *fields).first()
        if row:
            if isinstance(map_fields, dict):
                record = Storage([(f, row[map_fields[f]]) for f in map_fields])
            else:
                record = Storage(row)
    elif isinstance(data, dict):
        record = Storage([(f, data[f]) for f in data if ((f in table.fields) and table[f].writable)])
    if record:
        missing_fields = Storage()
        for f in table.fields:
            if ((f not in record) and table[f].writable):
                missing_fields[f] = table[f].default
        record.update(missing_fields)
        record[table._id.name] = None
    return record
