se adiciona @fields.on_change para ejecutar funcion cuando se cambian los varoles de algun attributo
FossilOrigin-Name: bee19b201f8c1a6b972c2a9abfe5fb57a558a67be6ecddce4f7f07b5b6980215
This commit is contained in:
		| @@ -1,4 +1,5 @@ | ||||
| from .fields import Field | ||||
| from collections import defaultdict | ||||
|  | ||||
| class ModelMeta(type): | ||||
|     def __new__(cls, name, bases, ns): | ||||
| @@ -20,6 +21,19 @@ class ModelBase(object, metaclass=ModelMeta): | ||||
|         obj._fields = {} | ||||
|         obj._text = "" | ||||
|         obj._namespace_prefix = None | ||||
|         obj._on_change_fields = defaultdict(list) | ||||
|          | ||||
|         def on_change_fields_for_function(function_name): | ||||
|             # se recorre arbol buscando el primero | ||||
|             for parent_cls in type(obj).__mro__: | ||||
|                 parent_meth = getattr(parent_cls, function_name, None) | ||||
|                 if not parent_meth: | ||||
|                     continue | ||||
|                  | ||||
|                 on_changes = getattr(parent_meth, 'on_changes', None) | ||||
|                 if on_changes: | ||||
|                     return on_changes | ||||
|             return [] | ||||
|  | ||||
|         # forzamos registros de campos al modelo | ||||
|         # al instanciar | ||||
| @@ -28,7 +42,12 @@ class ModelBase(object, metaclass=ModelMeta): | ||||
|                 if hasattr(v, 'default') and v.default is not None: | ||||
|                     setattr(obj, key, v.default) | ||||
|  | ||||
|  | ||||
|                 # register callbacks for changes | ||||
|                 function_name = 'on_change_%s' % (key) | ||||
|                 on_change_fields = on_change_fields_for_function(function_name) | ||||
|                 for field in on_change_fields: | ||||
|                     obj._on_change_fields[field].append(function_name) | ||||
|          | ||||
|         return obj | ||||
|  | ||||
|     def _set_attribute(self, field, name, value): | ||||
|   | ||||
| @@ -6,3 +6,15 @@ from .virtual import Virtual | ||||
| from .field import Field | ||||
|  | ||||
| __all__ = [Attribute, Many2One, Model, Virtual, Field] | ||||
|  | ||||
| def on_change(fields): | ||||
|     from functools import wraps | ||||
|      | ||||
|     def decorator(func): | ||||
|         setattr(func, 'on_changes', fields) | ||||
|  | ||||
|         @wraps(func) | ||||
|         def wrapper(self, *arg, **kwargs): | ||||
|             return func(self, *arg, **kwargs) | ||||
|         return wrapper | ||||
|     return decorator | ||||
|   | ||||
| @@ -16,4 +16,6 @@ class Attribute(Field): | ||||
|     def __set__(self, inst, value): | ||||
|         assert self.name is not None | ||||
|         self.value = value | ||||
|          | ||||
|         self._changed_field(inst, self.name, value) | ||||
|         inst._set_attribute(self.name, self.attribute, value) | ||||
|   | ||||
| @@ -39,3 +39,8 @@ class Field: | ||||
|             self._set_namespace(obj, self.namespace, inst.__namespace__) | ||||
|             inst._fields[self.name] = obj | ||||
|             return obj | ||||
|  | ||||
|     def _changed_field(self, inst, name, value): | ||||
|         for fun in inst._on_change_fields[name]: | ||||
|             getattr(inst, fun)(name, value) | ||||
|              | ||||
|   | ||||
| @@ -31,4 +31,5 @@ class Function(Field): | ||||
|  | ||||
|     def __set__(self, inst, value): | ||||
|         inst._set_field(self.name, self.field) | ||||
|         self._changed_field(inst, self.name, value) | ||||
|         self.field.__set__(inst, value) | ||||
|   | ||||
| @@ -25,6 +25,7 @@ class Many2One(Field): | ||||
|             setter(inst_model, value) | ||||
|         else: | ||||
|             inst_model._set_content(value) | ||||
|  | ||||
|              | ||||
|         self._changed_field(inst, self.name, value) | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user