- def contribute_to_class(self, cls, name):
- super (DenormalizedField, self).contribute_to_class(cls, name)
- if not hasattr(cls, '_denormalizad_fields'):
- cls._denormalizad_fields = []
+ if val is None:
+ val = getattr(inst, self.manager).filter(**self.filter).count()
+ inst.__dict__[dict_name] = val
+ inst.__class__.objects.cache_obj(inst)
+
+ return val
+
+ def reset_cache(inst):
+ inst.__dict__.pop(dict_name, None)
+ inst.__class__.objects.cache_obj(inst)
+
+ cls.add_to_class(name, property(getter))
+ cls.add_to_class("reset_%s_cache" % name, reset_cache)
+
+
+class BaseMetaClass(models.Model.__metaclass__):
+ to_denormalize = []
+
+ def __new__(cls, *args, **kwargs):
+ new_cls = super(BaseMetaClass, cls).__new__(cls, *args, **kwargs)
+
+ BaseMetaClass.to_denormalize.extend(
+ [(new_cls, name, field) for name, field in new_cls.__dict__.items() if isinstance(field, DenormalizedField)]
+ )
+
+ return new_cls
+
+ @classmethod
+ def setup_denormalizes(cls):
+ for new_cls, name, field in BaseMetaClass.to_denormalize:
+ field.setup_class(new_cls, name)