[FIX] fields: allow overriding of a old-api function field

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).
This commit is contained in:
Raphael Collet 2015-02-19 14:01:19 +01:00
parent bfb877a671
commit 9333c622e9
3 changed files with 17 additions and 7 deletions

View File

@ -637,8 +637,11 @@ class Field(object):
#
def to_column(self):
""" return a low-level field object corresponding to `self` """
assert self.store or self.column
""" Return a column object corresponding to `self`, or ``None``. """
if not self.store and self.compute:
# non-stored computed fields do not have a corresponding column
self.column = None
return None
# determine column parameters
#_logger.debug("Create fields._column for Field %s", self)
@ -674,6 +677,7 @@ class Field(object):
_column_groups = property(attrgetter('groups'))
_column_change_default = property(attrgetter('change_default'))
_column_deprecated = property(attrgetter('deprecated'))
_column_compute = property(lambda self: bool(self.compute))
############################################################################
#

View File

@ -2986,8 +2986,9 @@ class BaseModel(object):
cls._columns = {}
for name, field in cls._fields.iteritems():
field.setup(self.env)
if field.store or field.column:
cls._columns[name] = field.to_column()
column = field.to_column()
if column:
cls._columns[name] = column
# group fields by compute to determine field.computed_fields
fields_by_compute = defaultdict(list)

View File

@ -1293,9 +1293,14 @@ class function(_column):
self._symbol_set = type_class._symbol_set
def new(self, **args):
# HACK: function fields are tricky to recreate, simply return a copy
import copy
return copy.copy(self)
if args.get('compute'):
# field is computed, we need an instance of the given type
type_class = globals()[self._type]
return type_class(**args)
else:
# HACK: function fields are tricky to recreate, simply return a copy
import copy
return copy.copy(self)
def to_field_args(self):
args = super(function, self).to_field_args()