503 lines
14 KiB
ReStructuredText
503 lines
14 KiB
ReStructuredText
.. _reference/orm:
|
||
|
||
===
|
||
ORM
|
||
===
|
||
|
||
.. _reference/orm/model:
|
||
|
||
Model
|
||
=====
|
||
|
||
.. - can't get autoattribute to import docstrings, so use regular attribute
|
||
- no autoclassmethod
|
||
|
||
.. currentmodule:: openerp.models
|
||
|
||
.. autoclass:: openerp.models.Model
|
||
|
||
.. rubric:: Structural attributes
|
||
|
||
.. attribute:: _name
|
||
|
||
business object name, in dot-notation (in module namespace)
|
||
|
||
.. attribute:: _rec_name
|
||
|
||
Alternative field to use as name, used by osv’s name_get()
|
||
(default: ``'name'``)
|
||
|
||
.. attribute:: _inherit
|
||
|
||
* If :attr:`._name` is set, names of parent models to inherit from.
|
||
Can be a ``str`` if inheriting from a single parent
|
||
* If :attr:`._name` is unset, name of a single model to extend
|
||
in-place
|
||
|
||
See :ref:`reference/orm/inheritance`.
|
||
|
||
.. attribute:: _order
|
||
|
||
Ordering field when searching without an ordering specified (default:
|
||
``'id'``)
|
||
|
||
:type: str
|
||
|
||
.. attribute:: _auto
|
||
|
||
Whether a database table should be created (default: ``True``)
|
||
|
||
If set to ``False``, override :meth:`.init` to create the database
|
||
table
|
||
|
||
.. attribute:: _table
|
||
|
||
Name of the table backing the model created when
|
||
:attr:`~openerp.models.Model._auto`, automatically generated by
|
||
default.
|
||
|
||
.. attribute:: _inherits
|
||
|
||
dictionary mapping the _name of the parent business objects to the
|
||
names of the corresponding foreign key fields to use::
|
||
|
||
_inherits = {
|
||
'a.model': 'a_field_id',
|
||
'b.model': 'b_field_id'
|
||
}
|
||
|
||
implements composition-based inheritance: the new model exposes all
|
||
the fields of the :attr:`~openerp.models.Model._inherits`-ed model but
|
||
stores none of them: the values themselves remain stored on the linked
|
||
record.
|
||
|
||
.. warning::
|
||
|
||
if the same field is defined on multiple
|
||
:attr:`~openerp.models.Model._inherits`-ed
|
||
|
||
.. attribute:: _constraints
|
||
|
||
list of ``(constraint_function, message, fields)`` defining Python
|
||
constraints. The fields list is indicative
|
||
|
||
.. deprecated:: 8.0
|
||
|
||
use :func:`~openerp.api.constrains`
|
||
|
||
.. attribute:: _sql_constraints
|
||
|
||
list of ``(name, sql_definition, message)`` triples defining SQL
|
||
constraints to execute when generating the backing table
|
||
|
||
.. attribute:: _parent_store
|
||
|
||
Alongside :attr:`~.parent_left` and :attr:`~.parent_right`, sets up a
|
||
`nested set <http://en.wikipedia.org/wiki/Nested_set_model>`_ to
|
||
enable fast hierarchical queries on the records of the current model
|
||
(default: ``False``)
|
||
|
||
:type: bool
|
||
|
||
.. rubric:: CRUD
|
||
|
||
.. automethod:: create
|
||
.. automethod:: browse
|
||
.. automethod:: unlink
|
||
.. automethod:: write
|
||
|
||
.. automethod:: read
|
||
|
||
.. rubric:: Research
|
||
|
||
.. automethod:: search
|
||
.. automethod:: search_count
|
||
.. automethod:: name_search
|
||
|
||
.. rubric:: Recordset operations
|
||
|
||
.. autoattribute:: ids
|
||
.. automethod:: ensure_one
|
||
.. automethod:: exists
|
||
.. automethod:: filtered
|
||
.. automethod:: sorted
|
||
.. automethod:: update
|
||
|
||
.. rubric:: Environment swapping
|
||
|
||
.. automethod:: sudo
|
||
.. automethod:: with_context
|
||
.. automethod:: with_env
|
||
|
||
.. rubric:: Fields and views querying
|
||
|
||
.. automethod:: fields_get
|
||
.. automethod:: fields_view_get
|
||
|
||
.. rubric:: ???
|
||
|
||
.. automethod:: default_get
|
||
.. automethod:: copy
|
||
.. automethod:: name_get
|
||
.. automethod:: name_create
|
||
|
||
.. _reference/orm/model/automatic:
|
||
|
||
.. rubric:: Automatic fields
|
||
|
||
.. attribute:: id
|
||
|
||
Identifier :class:`field <openerp.fields.Field>`
|
||
|
||
.. attribute:: _log_access
|
||
|
||
Whether log access fields (``create_date``, ``write_uid``, ...) should
|
||
be generated (default: ``True``)
|
||
|
||
.. attribute:: create_date
|
||
|
||
Date at which the record was created
|
||
|
||
:type: :class:`~openerp.field.Datetime`
|
||
|
||
.. attribute:: create_uid
|
||
|
||
Relational field to the user who created the record
|
||
|
||
:type: ``res.users``
|
||
|
||
.. attribute:: write_date
|
||
|
||
Date at which the record was last modified
|
||
|
||
:type: :class:`~openerp.field.Datetime`
|
||
|
||
.. attribute:: write_uid
|
||
|
||
Relational field to the last user who modified the record
|
||
|
||
:type: ``res.users``
|
||
|
||
.. rubric:: Reserved field names
|
||
|
||
A few field names are reserved for pre-defined behaviors beyond that of
|
||
automated fields. They should be defined on a model when the related
|
||
behavior is desired:
|
||
|
||
.. attribute:: name
|
||
|
||
default value for :attr:`~._rec_name`, used to
|
||
display records in context where a representative "naming" is
|
||
necessary.
|
||
|
||
:type: :class:`~openerp.fields.Char`
|
||
|
||
.. attribute:: active
|
||
|
||
toggles the global visibility of the record, if ``active`` is set to
|
||
``False`` the record is invisible in most searches and listing
|
||
|
||
:type: :class:`~openerp.fields.Boolean`
|
||
|
||
.. attribute:: sequence
|
||
|
||
Alterable ordering criteria, allows drag-and-drop reordering of models
|
||
in list views
|
||
|
||
:type: :class:`~openerp.fields.Integer`
|
||
|
||
.. attribute:: state
|
||
|
||
lifecycle stages of the object, used by the ``states`` attribute on
|
||
:class:`fields <openerp.fields.Field>`
|
||
|
||
:type: :class:`~openerp.fields.Selection`
|
||
|
||
.. attribute:: parent_id
|
||
|
||
used to order records in a tree structure and enables the ``child_of``
|
||
operator in domains
|
||
|
||
:type: :class:`~openerp.fields.Many2one`
|
||
|
||
.. attribute:: parent_left
|
||
|
||
used with :attr:`~._parent_store`, allows faster tree structure access
|
||
|
||
.. attribute:: parent_right
|
||
|
||
see :attr:`~.parent_left`
|
||
|
||
.. _reference/orm/decorators:
|
||
|
||
Method decorators
|
||
=================
|
||
|
||
.. automodule:: openerp.api
|
||
:members: one, multi, model, depends, constrains, onchange, returns
|
||
|
||
.. _reference/orm/fields:
|
||
|
||
Fields
|
||
======
|
||
|
||
.. _reference/orm/fields/basic:
|
||
|
||
Basic fields
|
||
------------
|
||
|
||
.. autodoc documents descriptors as attributes, even for the *definition* of
|
||
descriptors. As a result automodule:: openerp.fields lists all the field
|
||
classes as attributes without providing inheritance info or methods (though
|
||
we don't document methods as they're not useful for "external" devs)
|
||
(because we don't support pluggable field types) (or do we?)
|
||
|
||
.. autoclass:: openerp.fields.Field
|
||
|
||
.. autoclass:: openerp.fields.Char
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Boolean
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Integer
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Float
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Text
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Selection
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Html
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Date
|
||
:show-inheritance:
|
||
:members: today, context_today, from_string, to_string
|
||
|
||
.. autoclass:: openerp.fields.Datetime
|
||
:show-inheritance:
|
||
:members: now, context_timestamp, from_string, to_string
|
||
|
||
.. _reference/orm/fields/relational:
|
||
|
||
Relational fields
|
||
-----------------
|
||
|
||
.. autoclass:: openerp.fields.Many2one
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.One2many
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Many2many
|
||
:show-inheritance:
|
||
|
||
.. autoclass:: openerp.fields.Reference
|
||
:show-inheritance:
|
||
|
||
.. _reference/orm/inheritance:
|
||
|
||
Inheritance and extension
|
||
=========================
|
||
|
||
Odoo provides three different mechanisms to extend models in a modular way:
|
||
|
||
* creating a new model from an existing one, adding new information to the
|
||
copy but leaving the original module as-is
|
||
* extending models defined in other modules in-place, replacing the previous
|
||
version
|
||
* delegating some of the model's fields to records it contains
|
||
|
||
.. image:: ../images/inheritance_methods.png
|
||
:align: center
|
||
|
||
Classical inheritance
|
||
---------------------
|
||
|
||
When using the :attr:`~openerp.models.Model._inherit` and
|
||
:attr:`~openerp.models.Model._name` attributes together, Odoo creates a new
|
||
model using the existing one (provided via
|
||
:attr:`~openerp.models.Model._inherit`) as a base. The new model gets all the
|
||
fields, methods and meta-information (defaults & al) from its base.
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/inheritance.py
|
||
:language: python
|
||
:lines: 5-
|
||
|
||
and using them:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_inheritance.py
|
||
:language: python
|
||
:lines: 8,12,9,19
|
||
|
||
will yield:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_inheritance.py
|
||
:language: text
|
||
:lines: 15,22
|
||
|
||
the second model has inherited from the first model's ``check`` method and its
|
||
``name`` field, but overridden the ``call`` method, as when using standard
|
||
:ref:`Python inheritance <python:tut-inheritance>`.
|
||
|
||
Extension
|
||
---------
|
||
|
||
When using :attr:`~openerp.models.Model._inherit` but leaving out
|
||
:attr:`~openerp.models.Model._name`, the new model replaces the existing one,
|
||
essentially extending it in-place. This is useful to add new fields or methods
|
||
to existing models (created in other modules), or to customize or reconfigure
|
||
them (e.g. to change their default sort order):
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/extension.py
|
||
:language: python
|
||
:lines: 5-
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_extension.py
|
||
:language: python
|
||
:lines: 8,13
|
||
|
||
will yield:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_extension.py
|
||
:language: text
|
||
:lines: 11
|
||
|
||
.. note:: it will also yield the various :ref:`automatic fields
|
||
<reference/orm/model/automatic>` unless they've been disabled
|
||
|
||
Delegation
|
||
----------
|
||
|
||
The third inheritance mechanism provides more flexibility (it can be altered
|
||
at runtime) but less power: using the :attr:`~openerp.models.Model._inherits`
|
||
a model *delegates* the lookup of any field not found on the current model
|
||
to "children" models. The delegation is performed via
|
||
:class:`~openerp.fields.Reference` fields automatically set up on the parent
|
||
model:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/delegation.py
|
||
:language: python
|
||
:lines: 5-
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_delegation.py
|
||
:language: python
|
||
:lines: 9-12,21,26
|
||
|
||
will result in:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_delegation.py
|
||
:language: text
|
||
:lines: 23,28
|
||
|
||
and it's possible to write directly on the delegated field:
|
||
|
||
.. literalinclude:: ../../openerp/addons/test_documentation_examples/tests/test_delegation.py
|
||
:language: python
|
||
:lines: 47
|
||
|
||
.. warning:: when using delegation inheritance, methods are *not* inherited,
|
||
only fields
|
||
|
||
.. _reference/orm/domains:
|
||
|
||
Domains
|
||
=======
|
||
|
||
A domain is a list of criteria, each criterion being a triple (either a
|
||
``list`` or a ``tuple``) of ``(field_name, operator, value)`` where:
|
||
|
||
``field_name`` (``str``)
|
||
a field name of the current model, or a relationship traversal through
|
||
a :class:`~openerp.fields.Many2one` using dot-notation e.g. ``'street'``
|
||
or ``'partner_id.country'``
|
||
``operator`` (``str``)
|
||
an operator used to compare the ``field_name`` with the ``value``. Valid
|
||
operators are:
|
||
|
||
``=``
|
||
equals to
|
||
``!=``
|
||
not equals to
|
||
``>``
|
||
greater than
|
||
``>=``
|
||
greater than or equal to
|
||
``<``
|
||
less than
|
||
``<=``
|
||
less than or equal to
|
||
``=?``
|
||
unset or equals to (returns true if ``value`` is either ``None`` or
|
||
``False``, otherwise behaves like ``=``)
|
||
``=like``
|
||
matches ``field_name`` against the ``value`` pattern. An underscore
|
||
``_`` in the pattern stands for (matches) any single character; a
|
||
percent sign ``%`` matches any string of zero or more characters.
|
||
``like``
|
||
matches ``field_name`` against the ``%value%`` pattern. Similar to
|
||
``=like`` but wraps ``value`` with '%' before matching
|
||
``not like``
|
||
doesn't match against the ``%value%`` pattern
|
||
``ilike``
|
||
case insensitive ``like``
|
||
``not ilike``
|
||
case insensitive ``not like``
|
||
``=ilike``
|
||
case insensitive ``=like``
|
||
``in``
|
||
is equal to any of the items from ``value``, ``value`` should be a
|
||
list of items
|
||
``not in``
|
||
is unequal to all of the items from ``value``
|
||
``child_of``
|
||
is a child (descendant) of a ``value`` record.
|
||
|
||
Takes the semantics of the model into account (i.e following the
|
||
relationship field named by
|
||
:attr:`~openerp.models.Model._parent_name`).
|
||
|
||
``value``
|
||
variable type, must be comparable (through ``operator``) to the named
|
||
field
|
||
|
||
Domain criteria can be combined using logical operators in *prefix* form:
|
||
|
||
``'&'``
|
||
logical *AND*, default operation to combine criteria following one
|
||
another. Arity 2 (uses the next 2 criteria or combinations).
|
||
``'|'``
|
||
logical *OR*, arity 2.
|
||
``'!'``
|
||
logical *NOT*, arity 1.
|
||
|
||
.. tip:: Mostly to negate combinations of criteria
|
||
:class: aphorism
|
||
|
||
Individual criterion generally have a negative form (e.g. ``=`` ->
|
||
``!=``, ``<`` -> ``>=``) which is simpler than negating the positive.
|
||
|
||
.. admonition:: Example
|
||
|
||
To search for partners named *ABC*, from belgium or germany, whose language
|
||
is not english::
|
||
|
||
[('name','=','ABC'),
|
||
('language.code','!=','en_US'),
|
||
'|',('country_id.code','=','be'),
|
||
('country_id.code','=','de')]
|
||
|
||
This domain is interpreted as:
|
||
|
||
.. code-block:: text
|
||
|
||
(name is 'ABC')
|
||
AND (language is NOT english)
|
||
AND (country is Belgium OR Germany)
|
||
|