From dbb4044edd67669e5c88df85cb3a569f782d7a36 Mon Sep 17 00:00:00 2001 From: Paul Eipper Date: Tue, 28 Jun 2016 19:21:06 -0300 Subject: [PATCH] TEMP SERIALIZABLE --- schematics/models.py | 7 +++++-- schematics/transforms.py | 14 ++++++++++++-- schematics/types/serializable.py | 15 +++++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/schematics/models.py b/schematics/models.py index f397bf8..b737d87 100644 --- a/schematics/models.py +++ b/schematics/models.py @@ -51,7 +51,10 @@ class FieldDescriptor(object): """ Sets the field's value. """ - field = instance._fields[self.name] + try: + field = instance._fields[self.name] + except KeyError: + field = instance._serializables[name] value = field.pre_setattr(value) instance._data[self.name] = value @@ -358,7 +361,7 @@ class Model(object): raise UnknownFieldError(self, name) def __setitem__(self, name, value): - if name in self._fields: + if name in self._fields or name in self._serializables: return setattr(self, name, value) else: raise UnknownFieldError(self, name) diff --git a/schematics/transforms.py b/schematics/transforms.py index 8ede4e2..4e9d932 100644 --- a/schematics/transforms.py +++ b/schematics/transforms.py @@ -114,7 +114,8 @@ def import_loop(cls, instance_or_dict, field_converter=None, trusted_data=None, for field in rogue_fields: errors[field] = 'Rogue field' - for field_name, field in cls._field_list: + for field_name, field in itertools.chain(cls._fields.iteritems(), + ((s[0], s[1].type) for s in cls._serializables.iteritems())): value = Undefined serialized_field_name = field.serialized_name or field_name @@ -122,7 +123,11 @@ def import_loop(cls, instance_or_dict, field_converter=None, trusted_data=None, if got_data: for key in field.get_input_keys(context.mapping): if key and key in instance_or_dict: - value = instance_or_dict[key] + if field_name in cls._serializables: + value = getattr(instance_or_dict, '_data', instance_or_dict)[key] + value = value or instance_or_dict[key] + else: + value = instance_or_dict[key] break if value is Undefined: @@ -164,6 +169,11 @@ def import_loop(cls, instance_or_dict, field_converter=None, trusted_data=None, data = context.field_converter.post(cls, data, context) + if hasattr(instance_or_dict, '_data'): + for field_name, serializable in cls._serializables.iteritems(): + value = data[field_name] + setattr(instance_or_dict, field_name, value) + return data diff --git a/schematics/types/serializable.py b/schematics/types/serializable.py index 7a4c0ab..5584b22 100644 --- a/schematics/types/serializable.py +++ b/schematics/types/serializable.py @@ -56,16 +56,17 @@ def serializable(arg=None, **kwargs): serialized_type = serialized_type(**kwargs) if decorator: - return Serializable(func, serialized_type) + return Serializable(func, type=serialized_type) else: return partial(Serializable, type=serialized_type) class Serializable(object): - def __init__(self, func, type): + def __init__(self, func, type, fset=None): self.func = func self.type = type + self.fset = fset def __getattr__(self, name): return getattr(self.type, name) @@ -80,6 +81,16 @@ class Serializable(object): else: return value + def __set__(self, instance, value): + if self.fset is None: + raise AttributeError("can't set attribute") + value = self.type.pre_setattr(value) + self.fset(instance, value) + + def setter(self, fset): + self.fset = fset + return self + def __deepcopy__(self, memo): return self.__class__(self.func, copy.deepcopy(self.type)) -- 2.8.1