Our usage of domain on fields One2many seems to trigger an obscure behaviour on
onchange.
With the following (simplified) config:
Message(models.Model):
_name = 'test_new_api.message'
important = fields.Boolean('Important')
Discussion(models.Model):
_name = 'test_new_api.discussion'
name = fields.Char('Name')
important_emails = fields.One2Many('test_new_api.emailmessage', 'discussion',
domain=[('important', '=', True)])
Email(models.Model):
_name = 'test_new_api.emailmessage'
_inherits = {'test_new_api.message': 'message'}
discussion = fields.Many2one('test_new_api.discussion', 'Discussion')
message = fields.Many2one('test_new_api.message', 'Message')
Steps:
- We change 'name' on discussion, triggers an `onchange()` call
- we ends up filling cache on virtual record (on secondary fields, we calling
record.mapped('important_emails.important'))
- we get a cache miss ('important' field not provided, only 'important_emails' ids,
i.e with no change on existing records)
- we fill the cache, this mark 'important' field as modified
- because of commit 5676d81 and because 'important' is that case is a related (i.e
computed) field we triggers cache recomputation
- as there is no way to recompute 'important_emails' for virtual record (no real
ID) we ends up with empty 'important_emails' generating removal of existing records.
=> Finally changing any value for 'test_new_api.discussion' that trigger an onchange
will always reset 'important_emails' to empty
Fixed by Raphael Collet <rco@odoo.com>, and test by Xavier Alt <xal@odoo.com>.
Invalidate the cache of a x2many field when any of the fields appearing in its
domain is modified. Use the invalidation triggers mechanism for that purpose.
When traversing relational fields as superuser, you end up with a recordset for
which only a subset is accessible to the current user. An earlier fix to this
issue completely dropped the `related_sudo` feature; change its implementation
to keep the feature.
The recursion was based on an incorrect assumption: the cache of the target
environment is initially empty. If another computation left some value there,
the copying is incomplete, and that causes bugs in onchanges.
Accessing a related field with `related_sudo=True` on a draft record should
effectively traverse the fields as the admin user. Traversing new records in a
different cache requires that all new records on the path are copied across
caches. Make the copy across caches recursive when the first record on the
path is a new record.
This reverts commits
- 995b257a6c
- 2ebdb5f36e
- 748a719fd9.
The commit 748a719fd9 leads to an issue
bigger than what it aims to solve:
- as demo user
- create a new invoice
- add a new line
- select a product
-> traceback
opw-668141
Borrowing a cursor each time you access `field.digits` may be costly, because
of the connection reset. Moreover, in most cases, the cursor is not used at
all, since the decimal precision are kept in cache.
For the installation of module `product` with its demo data, the number of
cursor allocations was reduced from ~1500 to about 50!
Traversing new records in a different cache requires that all new records on
the path are copied across caches. Make the copy across caches recursive when
the first record on the path is a new record.
The serialization gives different results for some elements. For instance, an
empty element `i` must be serialized as `<i/>` in XML and `<i></i>` in HTML.
It must be done like that, otherwise the world (of web browsers) would break.
Add a test case for `html_translate`.
Such a field is declared as:
image = fields.Binary("Image", attachment=True)
With this option, the value of a binary field F is stored in an attachment with
`res_field=F`. When attachments are stored into the filestore, binary fields
are consequently stored in the filestore as well. Note that the option does
not work on old-API function fields.
By default searching on `ir.attachment` filters out attachments for binary
fields: the condition `res_field=False` is added to the domain unless a
condition on field `id` or `res_field` is already present. The client uses
`search_read` with a domain like `[('id', 'in', ids)]` for reading the data on
a form view. In that case, we should not filter out attachments that store
binary fields.
Also, do not filter search results for the superuser.