diff --git a/cassandra/cqlengine/columns.py b/cassandra/cqlengine/columns.py index be204a89..35a70e90 100644 --- a/cassandra/cqlengine/columns.py +++ b/cassandra/cqlengine/columns.py @@ -47,7 +47,7 @@ class BaseValueManager(object): :rtype: boolean """ - return self.value != self.previous_value + return self.explicit and self.value != self.previous_value def reset_previous_value(self): self.previous_value = deepcopy(self.value) @@ -57,6 +57,7 @@ class BaseValueManager(object): def setval(self, val): self.value = val + self.explicit = True def delval(self): self.value = None diff --git a/cassandra/cqlengine/models.py b/cassandra/cqlengine/models.py index 280f7161..f6019087 100644 --- a/cassandra/cqlengine/models.py +++ b/cassandra/cqlengine/models.py @@ -407,8 +407,6 @@ class BaseModel(object): value = column.to_python(value) value_mngr = column.value_manager(self, column, value) value_mngr.explicit = name in values - if not value_mngr.explicit and column.has_default: - value_mngr.previous_value = value self._values[name] = value_mngr def __repr__(self): @@ -490,7 +488,8 @@ class BaseModel(object): return instance def _set_persisted(self): - for v in self._values.values(): + # ensure we don't modify to any values not affected by the last save/update + for v in [v for v in self._values.values() if v.changed]: v.reset_previous_value() v.explicit = False self._is_persisted = True @@ -591,6 +590,10 @@ class BaseModel(object): return cls._table_name + def _set_column_value(self, name, value): + """Function to change a column value without changing then value manager states""" + self._values[name].value = value # internal assignement, skip the main setter + def validate(self): """ Cleans and validates the field values @@ -600,7 +603,7 @@ class BaseModel(object): if v is None and not self._values[name].explicit and col.has_default: v = col.get_default() val = col.validate(v) - setattr(self, name, val) + self._set_column_value(name, val) # Let an instance be used like a dict of its columns keys/values def __iter__(self):