Skip to content

Instantly share code, notes, and snippets.

@dreispt
Last active August 29, 2015 14:04
Show Gist options
  • Save dreispt/a7563035e7c0ba1bca19 to your computer and use it in GitHub Desktop.
Save dreispt/a7563035e7c0ba1bca19 to your computer and use it in GitHub Desktop.

may be written as:

env = Env(cr, uid, context) # cr, uid, context wrapped in env
recs = env[MODEL] # retrieve an instance of MODEL
recs = recs.search(DOMAIN) # search returns a recordset
for rec in recs: # iterate over the records
print rec.name
recs.write(VALUES) # update all records in recs

Base class for OpenERP models.

OpenERP models are created by inheriting from this class' subclasses:

  • class Model for regular database-persisted models
  • class TransientModel for temporary data, stored in the database but automatically vaccuumed every so often
  • class AbstractModel for abstract super classes meant to be shared by multiple inheriting model

load(fields, data)

Load/import the data matrix.

  • fields list(str): list of fields to import
  • data list(list(str)): matrix of data to import.
  • returns {ids: list(int)|False, messages: [Message]}: Returns a list of ids (or False if error) and a list of messages.

search(args, offset=0, limit=None, order=None, count=False)

Search records based on a search domain.

  • args: list of tuples specifying the search domain [('field_name', 'operator', value), ...]. An empty list matches all records.
  • offset: optional number of results to skip in the returned values
  • limit: optional max number of records to return
  • order: optional columns to sort by (default: self._order=id)
  • count: optional, if True, returns a record count instead of a list of ids
  • returns list(ids)|int: list of ids of records matching the criteria, ot a record count.

Expressing a search domain (args)

Each tuple in the search domain needs to have 3 elements, in the form: ('field_name', 'operator', value), where:

  • field_name must be a valid name of field of the object model, possibly following many-to-one relationships using dot-notation, e.g 'street' or 'partner_id.country' are valid values.
  • operator must be a string with a valid comparison operator from this list: =, !=, >, >=, <, <=, like, ilike, in, not in, child_of, parent_left, parent_right. The child_of operator will look for records who are children or grand-children of a given record, according to the semantics of this model (i.e following the relationship field named by self._parent_name, by default parent_id.
  • value must be a valid value to compare with the values of field_name, depending on its type.

Domain criteria can be combined using 3 logical operators than can be added between tuples: '&' (logical AND, default), '|' (logical OR), '!' (logical NOT). These are prefix operators and the arity of the '&' and '|' operator is 2, while the arity of the '!' is just 1. Be very careful about this when you combine them the first time.

Here is an example of searching for Partners named ABC from Belgium and Germany whose language is not english ::

[('name','=','ABC'),'!',('language.code','=','en_US'),'|',('country_id.code','=','be'),('country_id.code','=','de'))

The '&' is omitted as it is the default, and of course we could have used '!=' for the language, but what this domain really represents is::

(name is 'ABC' AND (language is NOT english) AND (country is Belgium OR Germany))

write(vals)

Update records with the given field values.

  • vals* dict: field values to update, e.g {'field_name': new_field_value, ...}
  • returns: True

For a many2many field, a list of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics ::

(0, 0, { values }) link to a new record that needs to be created with the given values dictionary (1, ID, { values }) update the linked record with id = ID (write values on it) (2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well) (3, ID) cut the link to the linked record with id = ID (delete the relationship between the two objects but does not delete the target object itself) (4, ID) link to existing record with id = ID (adds a relationship) (5) unlink all (like using (3,ID) for all linked records) (6, 0, [IDs]) replace the list of linked IDs (like using (5) then (4,ID) for each ID in the list of IDs)

Example: [(6, 0, [8, 5, 6, 4])] sets the many2many to ids [8, 5, 6, 4]

For a one2many field, a lits of tuples is expected. Here is the list of tuple that are accepted, with the corresponding semantics ::

(0, 0, { values }) link to a new record that needs to be created with the given values dictionary (1, ID, { values }) update the linked record with id = ID (write values on it) (2, ID) remove and delete the linked record with id = ID (calls unlink on ID, that will delete the object completely, and the link to it as well)

Example: [(0, 0, {'field_name':field_value_record1, ...}), (0, 0, {'field_name':field_value_record2, ...})]

For a many2one field, simply use the ID of target record, which must already exist, or False to remove the link. For a reference field, use a string with the model name, a comma, and the target object id (example: 'product.product, 5')

create(self, vals): """ Create a new record for the model.

The values for the new record are initialized using the dictionary vals, and if necessary the result of :meth:default_get.

:param vals: field values like {'field_name': field_value, ...}, see :meth:write for details about the values format :return: new record created :raise AccessError: * if user has no create rights on the requested object

  • if user tries to bypass access rules for create on the requested object :raise ValidateError: if user tries to enter invalid value for a field that is not in selection :raise UserError: if a loop would be created in a hierarchy of objects a result of the operation (such as setting an object as its own parent)

copy(self, cr, uid, id, default=None, context=None): """ Duplicate record with given id updating it with default values

:param cr: database cursor :param uid: current user id :param id: id of the record to copy :param default: dictionary of field values to override in the original values of the copied record, e.g: {'field_name': overriden_value, ...} :type default: dictionary :param context: context arguments, like lang, time zone :type context: dictionary :return: id of the newly created record

get_external_id(self, cr, uid, ids, *args, **kwargs): """Retrieve the External ID of any database record, if there is one. This method works as a possible implementation for a function field, to be able to add it to any model object easily, referencing it as Model.get_external_id.

When multiple External IDs exist for a record, only one of them is returned (randomly).

:return: map of ids to their fully qualified XML ID, defaulting to an empty string when there's none (to be usable as a function field), e.g.::

{ 'id': 'module.ext_id', 'id2': '' }

print_report(self, cr, uid, ids, name, data, context=None): """ Render the report name for the given IDs. The report must be defined for this model, not another.

def with_env(self, env):
    """ Return an instance equivalent to `self` attached to `env`.

""" return self._browse(env, self._ids)

def sudo(self, user=SUPERUSER_ID):
    """ Return an instance equivalent to `self` attached to an environment

based on self.env with the given user. """ return self.with_env(self.env(user=user))

def with_context(self, *args, **kwargs):
    """ Return an instance equivalent to `self` attached to an environment

based on self.env with another context. The context is given by self._context or the positional argument if given, and modified by kwargs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment