This commit allows for not copying the currency_field attribute
of a monetary field when the monetary field is related,
and when the currency_field attribute is not explicit
Before this commit, the currency_field attribute on the related monetary
was set as the one on the distant model
After this commit, the currency_field attribute takes the field on the
current model
Though the test may appear like an incoherent use case,
it is on the contrary totally legit, as web_studio allows it
OPW 1903113
closesodoo/odoo#28144
Introduce official support for SVG files in the framework, including the
following parts:
1. When client-side SVG images are uploaded, the content is displayed until
you save using data URI scheme according RFC 2397 [1]. This scheme requires
to specify content format. Using hardcoded "image/png" works for all images
types except SVG.
Type-sniffing is done using "magic byte" detection via the first base64
encode byte, so that the proper data URI scheme can be used.
This should not cause SVG-related security problems as the file is
displayed through `<img>` tag, which does not allow SVG scripting [2].
2. Make /web/image controller compatible with SVG
3. Add support for SVG files for company logo, which uses a dedicated
controller.
4. Resizing of SVG files is a no-op, as it makes little sense for a
vector-based format. We also want to avoid micro-alterations to the SVG
document (in "natural" viewport parameters) as we would store multiple
copies of the files in the filestore.
5. Because SVG files are inherently dangerous, upload of SVG files is
restricted to administrators, either by blocking it directly before
saving it in the database (binary fields with attachment=False), or by
neutering them to text/plain mimetype (for binary fields with
attachment=True)
6. Add tests for the SVG upload cases and for the non-admin uploads.
[1] https://tools.ietf.org/html/rfc2397
[2] https://www.w3.org/wiki/SVG_SecurityCloses#26635
With this commit, any *explicitly* related fields will be `readonly=True`
by default.
*Implicitly* related fields (i.e. _inherits fields) however will keep the
source field's `readonly` attribute.
The rationales behind this patch are:
* Enforce good practices, as the most common use-case for
related fields is the same as for compute fields: to read data.
* Avoid errors where some user saves a form view which contains
a related field that the user doesn't have write access to.
When trying to upload a file with no ASCII name, it raised a
traceback saying: "UnicodeEncodeError: 'ascii' codec can't encode character ..."
opw:1886602
During an onchange, setting a many2one field automatically updates its inverse
one2many field. If the update raises an exception, catch it and put it in
cache, so that it is re-raised when the value is read from the cache.
Note: all costs are according to cprofile on my machine, as a fraction
of total time to import, python-flamegraph has somewhat different cost
distributions, YMMV. Profiles use test-import of a 2500 partners file,
with name, country, street and 0~4 tags, all randomly
generated/assigned.
Costs were profiled as split 8.5%/32%/57% between data conversion,
creating records (Model.create/Model._create) and populating stored
computed fields for a total import time (unprofiled) of 1mn (±2s or
something).
For the creation step, 27% (of total runtime) were assigned to the m2m
(fields.Many2many.create), almost all of which (25%) was assigned to
accessing a record's id in a listcomp in a loop.
Optimisations:
* optimise the case where we're only adding / creating values:
represent the relation as a dict of sets instead of a set of pairs;
commands 5 and 6 will only operate on the current record's value,
instead of traversing all pairs in the relation
* optimise accessing the value of an id field by hand-inlining the
various bits, this is mostly obviated by the other previous
optimisations (number of Id.__get__ calls reduced from 5.4 millions
to 0.55) but given how common accessing a record's id is (and
how it's usually considered to be free) it's still a good idea: cost
of accessing the id field was reduced by 75% (0.55 million accesses
went from 3.32% of total runtime to 0.83%)
Without profiling, time to import my test file went from ~1mn to ~45s.
Now that Date/Datetime fields use python naive datetime, we want
to prevent developper to call or assign aware datetime to
fields. Moreover, if so, the timezone will be stored in the
database, but when reading Datetime fields, we expect naive datetime.
Comparing naive and aware datetime objects leads to errors.
This commit forces developpers to use naive datetime when saving
data in database.
As example, we have to erase the timezone of dates in calendar
modules. We also regroup the 2 assignations in one call to
`write` for performance reason.
Thanks to @dbeguin and @RomainLibert for spending some time
on this bug.
Adds a checkbox to import columns (in debug mode) allowing a user to
create records M2O and M2M records not found (via name_search).
Task ID: 1850633
* uses a context key to avoid altering basically all the import callstack
* attempted to lift the creation in the `_str_to_*` functions and create
m2m via commands, but that doesn't really work out
From this commit onwards, Date fields will return datetime.date objects and Datetime fields will return datetime.datetime objects, this implies a number of things that are clearly explained both in the ORM API for master.
This commit also introduces a number of helper functions for dates and datetimes that are exposed in tools.date_utils and fields.Date[time], explained in the documentation as well.
Task-ID: 47189
When a string value is assigned to a selection field expecting integers, the
value simply rejected. In such a case, convert the value to an integer before
validating it.
When a record fields are prefetched, the currently accessed record is
prefetched as well as PREFETCH_MAX (=1000) minus currenly accessed
records.
Since 439fa826 the id field was thought as "prefetched" but was not,
which caused that in an onchange, we would have a prefetching as follow
for 1200 records:
- get records 1-1000
- get record 1001 (1001-1200 INTERSECTION 1-999 (id) + 1001 (current))
- get record 1002 (1002-1200 INTERSECTION 1-999 (id) + 1002 (current))
- get record 1003 (1003-1200 INTERSECTION 1-999 (id) + 1003 (current))
- ...
- get record 1200 (1200 INTERSECTION 1-999 (id) + 1200 (current))
So we would do 201 queries instead of 2 when prefetching the records.
The added test without this change failed the query count with:
"AssertionError: 284 not less than or equal to 5 : admin"
opw-1837548
opw-1837552
closes#24326
Assume a custom field F is defined on model 'res.partner'. The setup of F may
silently fail because of missing stuff. In that situation, setting up the
field inherited from F on model 'res.users' should also silently fail.
To reproduce the bug, install Invoicing, create a related custom field F on
'res.partner' with 'property_account_position_id.active', and install another
module. Setting up F after loading module 'base' will fail because the field
'property_account_position_id' does not exist yet. The error is not caught by
the inheritance of F on model 'res.users', and the installation crashes.
When the `create` or `write` method receives an empty string for a date
or a datetime field, PostgreSQL will fail since this is not an accepted
value for this field type.
We fallback on `None` for falsy values.
opw-1819336
@KangOl : watch out when forward-porting, the signature of
`convert_to_column` has changed in saas-14.
Given the following variables:
* Module A
* Module B
* Model M
* Field X of model M
If module A defines M.X and is installed, an xmlid for this field is
generated in the form of A.field_M_X
Before this commit:
If module B defines M.X as well and is installed after module A, no
xmlid is generated.
This means that if module A is uninstalled, the single xmlid pointing to
M.X will be deleted and thus, the field itself will be deleted as well,
therefore any views from module B referencing M.X will crash.
After this commit:
If module B (or any subsequent modules) define M.X, an xmlid will be
generated in the form of B.field_M_X.
If module A is uninstalled, the xmlid A.field_M_X will be deleted, but
B.field_M_X will remain and thus the field itself won't be deleted.
This system means that for a single actual field, there can be multiple
xmlids, each xmlid sharing the same field, thus the name "shared
fields".
Task ID 38016
Optimize the copy of the cache being made by related fields to compute
themselves. Instead of traversing records data in cache, follow the cache
structure itself and copy everything!
OPW 816125
Log an info when a field is computed and stored, but not all its dependencies
are stored. Also allow to set explicitly `depends` on a field; this is useful
to restrict the dependencies of a related field.
In other words, when a field F depends on a non-stored field G, it also depends
on G's dependencies. This guarantees that whenever a dependency of G is
modified, F will be invalidated and marked to recompute (if necessary).
The transitive closure of dependencies is not computed over stored fields.
Anyway stored fields already trigger the recomputation of their dependent
fields during their recomputation. The performance impact on the loading of a
registry is negligible (less than 1%), and the increase of recomputation
triggers is small (less than 10%).
Assuming that `field.cache_key(record)` is independent from `record.id`,
compute the cache key once for all records, and avoid using `browse` on all
record ids. This makes `get_records` about 20 times faster.
This has a good performance impact on `field.modified_draft()`, which is used
during onchanges for invalidating fields.