A frequent need when writing business logic methods is to create new records. This recipe explains how to create records of the res.partner
model, which is defined in Odoo's base
addon module. We will create a new partner representing a company, with some contacts.
You need to know the structure of the models for which you want to create a record, especially their names and types as well as any constraints existing on these fields (for example, whether some of them are mandatory). The res.partner
model defined in Odoo has a very large number of fields, and to keep things simple, we will only use a few of these. Moreover, the model definition in Odoo uses the old API. To help you follow the recipe, here is a port of the model definition we will be using for the new API:
class ResPartner(models.Model): _name = 'res.partner' name = fields.Char('Name', required=True) email = fields.Char('Email') date = fields.Date('Date') is_company = fields.Boolean('Is a company') parent_id = fields.Many2one('res.partner', 'Related Company') child_ids = fields.One2many('res.partner', 'parent_id', 'Contacts')
In order to create a partner with some contacts, you need to take the following steps:
create()
:today_str = fields.Date.context_today()
val1 = {'name': u'Eric Idle', 'email': u'[email protected]' 'date': today_str}
val2 = {'name': u'John Cleese', 'email': u'[email protected]', 'date': today_str}
partner_val = { 'name': u'Flying Circus', 'email': u'[email protected]', 'date': today_str, 'is_company': True, 'child_ids': [(0, 0, val1), (0, 0, val2), ] }
create()
method to create the new records:record = self.env['res.partner'].create(partner_val)
To create a new record for a model, we can call the create(values)
method on any recordset related to the model. This method returns a new recordset of length 1
containing the new record, with fields values specified in the values
dictionary.
In the dictionary:
Float
and Integer
field values are given using Python floats or integers.Boolean
field values are given, preferably using Python booleans or integer.Date
(resp. Datetime
) field values are given as Python strings. Use fields.Date.to_string()
(resp. fields.Datetime.to_string()
) to convert a Python datetime.date
(resp. datetime.datetime
) object to the expected format.Binary
field values are passed as a Base64 encoded string. The base64
module from the Python standard library provides methods such as encodestring(s)
to encode a string in Base64.Many2one
field values are given with an integer, which has to be the database ID of the related record.One2many
and Many2many
fields use a special syntax. The value is a list containing tuples of three elements, as follows:
Tuple |
Effect |
---|---|
|
Create a new record that will be related to the main record |
|
Create a relation between the record being created and existing records, whose IDs are in the Python list Caution: When used on a |
In the recipe, we create the dictionaries for two contacts in the company we want to create, and then we use these dictionaries in the child_ids
entry of the dictionary for the company being created, using the (0, 0, dict_val)
syntax explained previously.
When create()
is called in step 5, three records are created:
create
record.child_ids
If the model defined some default values for some fields, nothing special needs to be done; create()
will take care of computing the default values for the fields not present in the supplied dictionary.
On the other hand, onchange
methods are not called by create()
, because they are called by the web client during the initial edition of the record. Some of these methods compute default values for fields related to a given field. When creating records by hand you have to do the work yourself, either by providing explicit values or by calling the onchange methods. The Calling onchange methods on the server side recipe in Chapter 6, Advanced Server Side Development Techniques explains how to do this.