This was due to secondary fields loaded from database in 'onchange' mode. In
that mode, the secondary fields were marked 'dirty', and therefore returned by
the method `onchange`. The fix consists in loading those secondary fields in
cache before processing the onchanges.
This incidentally fixes a test on method `onchange`: in a one2many field, some
dirty fields were unexpectedly returned in the result. This was due to those
fields being loaded while processing onchanges.
When overriding a field defined as a function field, the field must either
create a corresponding column that is not a fields.function (if stored), or
have no corresponding column (if not stored).
Idea: look up for the model's fields in method `_setup_base()` instead of
method `__init__()`. This does not make a significant difference when
installing or upgrading modules, but when simply loading a registry, the
(expensive) field lookup is done once per model instead of once per class.
In a workflow context (for instance, in the invoice workflow),
context is not passed.
Therefore, relying on the 'recompute' key being the context
in order to not recompute the fields does not work with Workflows.
It leads to huge performance issues,
as fields are recomputed recursively (instead of sequentially)
when several records are implied.
For instance, when reconciling several invoices with one payment
(100 invoices with 1 payment for instance),
records of each invoice are recomputed uselessly in each workflow call
(for each "confirm_paid" method done for each invoice).
With a significant number of invoices (100, for instance),
it even leads to a "Maximum recursion depth reached" errror.
closes#4905
This fixes a bug introduced by commit f650522bbf
(related fields should not be copied by default). Inherited fields are a
particular case, and given the implementation of copy(), they must be copied if
their original field is copied.
The test on copy() in test_orm has been modified to show the bug.
This helps fixing old-api onchange methods with a record id as a parameter.
Browsing this record id may be problematic, since it reads the record in an
environment with an empty context. This is really problematic when the record
is a new record, because such a record only exists in a given environment.
The onchange() on new records processes fields in non-predictable order. This
is problematic when onchange methods are designed to be applied after each
other. The expected order is presumed to be the one of the fields in the view.
In order to implement this behavior, the JS client invokes method onchange()
with the list of fields (in view order) instead of False. The server then uses
that order for evaluating the onchange methods.
This fixes#4897.
If a selection field is created with an empty list of choices (e.g. added by
submodules), initialise the field as a varchar column (most common).
Check if the list exists to avoid crashing while checking the type of the first
key.
Fixes#3810
When changing the type of a column (if size differs for example),
'selection' field should be considered like a 'char' field (since they
are internaly the same column type)
This will fix some migration issues where 'char' fields were correctly
changed but not 'selection,' field.
Use case:
* create a 6.0 db with 'stock' module installed
* 'state' field in 'stock.move' model is of type 'character varying(16)'
* migrate it to 8.0
* 'state' field is still 'character varying(16)' but should normally be
'character varying'
These revs. introduced an API change in the _name_search method.
Indeed, the 'operator' attribute used to have 'ilike' as default value.
This cannot be changed, as every modules overriding this method
overrided it using the signature with operator='ilike'
For instance, _name_search method of addons/base/ir/ir_model.py
expects having 'ilike' as operator.
As it was not anymore the case,
it leaded to a crash when performing a name_search call on the model ir.model,
like when adding a new custom field to a model, from the web client.
opw-626161
The model setup sometimes misses entries in _inherit_fields and _all_columns.
This is because those dictionaries are computed from parent models which are
not guaranteed to be completely set up: sometimes a parent field is only
partially set up, and columns are missing (they are generated from fields after
their setup).
To avoid this bug, the setup has been split in three phases:
(1) determine all inherited and custom fields on models;
(2) setup fields, except for recomputation triggers, and generate columns;
(3) add recomputation triggers and complete the setup of the model.
Making these three phases explicit brings good invariants:
- when setting up a field, all models know all their fields;
- when adding recomputation triggers, you know that fields have been set up.
The field setup on models is improved: only fields are determined when building
the model's class; the final _columns is computed from the fields once they are
set up.
For models using a datetime field as name (hr.attendance for instance), the user timezone wasn't applied in the display name.
Therefore, in the breadcrumb, the datetime was different than in the form if the user had another timezone than UTC.
This rev. is related to 27d8cb843b, but is for the 8.0 api
We are aware we introduce a tiny change of API (method signature change), which we normally prohibit, but considering the really low level of the method, the fact it is probably not ovveriden by any other modules and the fact there is no cleaner way to correct this, we are making an exception.
Columns defined in the new api as interger, computed and non-stored should not be aggregated in read_group.
Fallback on False if column is None
Fixes#3972, opw 619536
Loading views for custom models from module data files was not possible because
custom models and fields were introduced into the registry after all modules
were loaded. As a consequence, the view architecture did not pass the checks.
This patch takes a different approach: custom models and fields are loaded
early on in the registry, so that views can be validated. The trick is to take
special care of relational custom fields: we skip them if their comodel does
not appear in the registry. This allows to install and upgrade modules that
create/modify custom models, fields and views for them.
* use static imports in java examples to make them terser
* inline ``domain`` in java and php example to make examples more
self-contained
* try to extend/improve Model.write's docstring
* add convenience kwarg to fields_get, mostly for user-driven
introspection
Closes#3689
When an onchange returns a change in a 2many field line (a '1' tuple, update), avoid to return all fields of the *2many field but only the altered field.
Otherwise, the web client regard all the fields of the 2many as dirty, and try to write on all fields (even if the value is the same, thus)
opw-615062
There was an issue in _setup_fields(): the method invokes _inherits_reload(),
which recomputes inherited fields, and invokes itself recursively on children
models. This may be problematic if the children models have already been set
up.
This optimization avoids recursive calls of method _inherits_reload(). In
_setup_fields(), first all parent models are set up, then their fields are
inspected to determine inherited fields, and their setup is done. This scheme
guarantees that inherited fields are computed once per model.
The old-api model._all_columns contains information about model._columns and
inherited columns. This dictionary is missing new-api computed non-stored
fields, and the new field objects provide a more readable api...
This commit contains the following changes:
- adapt several methods of BaseModel to use fields instead of columns and
_all_columns
- copy all semantic-free attributes of related fields from their source
- add attribute 'group_operator' on integer and float fields
- base, base_action_rule, crm, edi, hr, mail, mass_mailing, pad,
payment_acquirer, share, website, website_crm, website_mail: simply use
_fields instead of _all_columns
- base, decimal_precision, website: adapt qweb rendering methods to use fields
instead of columns
Clarify the semantics of field attributes:
- field.store is True when the field is actually stored in the database;
- field.column is the column corresponding to field or None.
The various field definitions correspond to:
- new-style stored field: field.store and field.column
- new-style non-stored field: not field.store and not field.column
- old-style regular field: field.store and field.column
- old-style function field: not field.store and field.column
Because some parameters of a field may be determined during its setup, we have
to update the corresponding column after the setup, and recompute _all_columns
to make it consistent.
The setup of relational fields may be problematic, as they may refer to unknown
models via custom relational fields. In a partial setup, do not try to skip
the field setup, but let it go and silently catch any exception if it crashes.
In the case of custom fields, the field's parameters were set up without the
field being present in the class hierarchy. Because of this, the parameter
inheritance mechanism was missing the field itself. As a consequence, custom
selection fields ended up without selection, for instance :-/