Compute methods could give results that should not be considered as default
values. For instance, a related field usually defaults to a null value, which
is then set to the field with its inverse method by create(). This may violate
a non-null constraint if the original field is required. Therefore, compute
methods are no longer used to determine default values.
The method _prefetch_field() was accidentally prefetching fields to recompute;
which was skipping the actual recomputation, since a value was put in cache.
But sometimes the field's value was fixed by an extra recomputation of the
field. Here we remove the extra recomputation and fix the cache corruption.
An issue occurs when a constraint is checked before computed fields are marked
for recomputation: the constraint will read the field's current value, which
may be wrong. If the field is marked soon enough, the constraint will trigger
the recomputation and use a correct value.
Because of the parameter overriding mechanism implemented by fields, it is no
longer necessary to copy field objects. It is even better to no copy them in
the case of related fields.
This solves a subtle issue: in the following case, the class Bar should
override the default value set by Foo. But in practice it was not working,
because _defaults is looked up before field.default.
class Foo(models.Model):
_name = 'foo'
_columns = {
'foo': fields.char('Foo'),
}
_defaults = {
'foo': "Foo",
}
class Bar(models.Model):
_inherit = 'foo'
foo = fields.Char(default="Bar")
The change makes field.default and the model's _defaults consistent with each
other.
Consider the following example:
class Foo(models.Model):
_name = 'foo'
_columns = {
'state': fields.selection([('a', 'A')]),
}
class Bar(models.Model):
_inherit = 'foo'
state = fields.Selection(selection_add=[('b', 'B')])
The attribute 'column' of the field does not have the full selection list,
therefore the column object cannot not be reused, even a copy of it. The
solution is to systematically recreate the column from the field's final
specification, except for function fields that have no sensible way for being
recreated.
When processing data files during a module installation/upgrade, not all fields
are set up yet, in particular relational custom fields. Make fields_get()
ignore those fields, so that views can be created/updated and validated,
provided they do not refer to those fields...
Replace the query "SELECT min(id) FROM xxx" by "SELECT 1 FROM xxx LIMIT 1".
Both requests are as efficient, and the second one does not crash if column
'id' is missing.
The method was expecting that name_get() returns complete and in-order values.
Because of this, some records in the recordset could end up without a value.
The method onchange() executes onchange methods in cascade. Suppose onchange()
is called and a field F=1 in the form. If an onchange method set F=2, that
value is put in the result variable. If another onchange method set it back to
F=1, the binding F=2 must be removed from the result variable.
Fixes#2309
Cascading onchanges can be caused by a related field computed in cache. This
causes a bug in sale order lines, were setting the uom field forces reading
product fields, which are inherited from product templates. The inherited
fields are computed as related fields, which marks the product record as dirty.
This subsequently triggers an onchange on the product field, which resets the
uom field!
This fixes issue #2146. The inverse of a one2many field can be an inherited
field (_inherits). In that case, we cannot read its value with a simple
database query. Instead, we let the related field read it, but for performance
considerations we disable the prefetching of other fields.
Add an attribute 'related_sudo' (True by default) for related fields.
A related field is computed as superuser if related_sudo is True.
Add explicit related fields 'name' and 'email' on 'res.users', as these should
be readable by the public user with module website_forum.
This fixes a bug which is usually triggered in module account_followup, but
does not occur deterministically. Some recomputations of computed fields are
apparently missing. Environment objects containing recomputations todos and
kept alive by a WeakSet, are removed by the Python garbage collector before
recomputation takes place. We fix the bug by moving the recomputation todos in
a non-weakref'ed object.
The selection of records in cache for prefetching was moved to method
_read_from_database() by xmo at rev 785018cc in order to fix an access right
bug. But this introduced an issue: to explicitly avoid prefetching, you should
use read() instead of browsing records. We revert the change by xmo, without
reintroducing the bug (which apparently was fixed by another way).
When the context contains 'recompute': False, the recomputation was not even
prepared. Now both create() and write() prepare the recomputation by invoking
method modified(). The flag only controls whether method recompute() is invoked.
In addintion, the former flag 'no_store_function' was converted to the flag
'recompute', so that both create() and write() use the same flag.
Fixes#1456
At the end of _prefetch_field(), a check is made to ensure that the cache
contains something for the field to prefetch. The check was incorrect because
the cache was checked for a regular value only.
The result of _convert_to_write() is intended to be pass directly to
`write()` or returned to the client (`onchange()` and `default_get()`.
`NewId` is as special value that must not be stored into the database
or exposed to the client.
On one2many fields writing in an existing record (not when creating new record), the computed stored fields of the one2many were not re-computed correctly
Computed stored fields were marked as modified only if no_store_function was not set to True in the context. no_store_function is set when writing one2many records on an existing record.
Now, these computed stored fields are marked as to be recomputed, but are recomputed later, at the end of the existing record write
After commit f28be81, boolean columns may have more
NULL entries than before. In the (rare) cases where
a boolean column was used for an ORDER clause
(e.g. in the /shop page of website_sale), this
causes a change of the resulting ordering.
By coalescing NULL values to false in SQL,
we make the ordering consistent with what the
framework does for domain expressions with booleans,
and when reading boolean values, that is, NULL is
the same as False.
Boolean fields always default to False in 8.0,
even when they do not have explicit default values.
This causes extra queries in the form:
UPDATE <table> SET <bool_field> = false
WHERE <bool_field> IS NULL;
Those are not necessary as the ORM automatically
folds NULL booleans to False, and can be very
expensive on tables with several million rows,
as the whole table may sometimes need to be
rewritten (can take dozens of minutes)
Some many2one fields happen to have several corresponding one2many fields,
typically with different domains. It is also the case for the field 'res_id' of
mail.message, where each model inheriting from mail.thread defines a one2many
based on that field. The fix ensures that when a relational field is updated,
all its inverse fields are invalidated.
The default values are computed by evaluating fields on a new record. The fix
retrieves values from the cache earlier, because in some cases, the evaluation
of a field invalidates a formerly evaluated field.
management to access documents in notification emails, as well as for the
'view quotation' link in portal_sale module.
models: added a get_access_action method: basically, returns the action to
access a document. It uses the get_formview_action by default (form view
of the document). However for some documents we want to directly go to the
website, leading to an act_url action for some documents. This method allows
this behavior.
portal_sale: get_signup_url now uses the mail.action_mail_redirect method
instead of directly redirecting towards a portal menu. This allows to fall
back on a standard behavior.
portal_sale: get_formview_action updated, to match actions tailored for
portal users.
website_quote: get_access_action of sale order updated. If the sale order
has a template defined, the returned action is an act_url (website view
of the quotation), not the form action anymore.
mail: fixed signature + company signature in notification emails. Even without
user signature, the company signature + access link should be correct.
portal: signup url in notification emali was not using the mail redirection
as action. It is now the case.
Singleton object was required while access model properties, but search returns multiple results and hence caused traceback while accessing record.property
The existing code was buggy when writing on *2many fields with a list of
commands: the value was converted for the cache, but taking an empty recordset
as the current value of the field.