Added fix to object.contents cache as well as reworked the extent of cache hooks on location modification.
This commit is contained in:
parent
07af616b67
commit
06a0bea8d6
11 changed files with 125 additions and 653 deletions
|
|
@ -97,27 +97,35 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
|||
update_fields = _GA(_GA(instance, "_meta"), "fields")
|
||||
for field in update_fields:
|
||||
fieldname = field.name
|
||||
new_value = _GA(instance, fieldname)#field.value_from_object(instance)
|
||||
# try to see if there is a handler on object that should be triggered when saving.
|
||||
handlername = "_at_%s_save" % fieldname
|
||||
handlername = "_at_%s_presave" % fieldname
|
||||
handler = _GA(instance, handlername) if handlername in _GA(sender, '__dict__') else None
|
||||
if callable(handler):
|
||||
#hid = hashid(instance, "-%s" % fieldname)
|
||||
try:
|
||||
old_value = _GA(instance, _GA(field, "get_cache_name")())
|
||||
except AttributeError:
|
||||
old_value=None
|
||||
# the handler may modify the stored value in various ways
|
||||
# don't catch exceptions, the handler must work!
|
||||
new_value = handler(new_value, old_value=old_value)
|
||||
# we re-assign this to the field, save() will pick it up from there
|
||||
_SA(instance, fieldname, new_value)
|
||||
handler()
|
||||
|
||||
def field_post_save(sender, instance=None, update_fields=None, raw=False, **kwargs):
|
||||
"""
|
||||
Called at the beginning of the field save operation. The save method
|
||||
must be called with the update_fields keyword in order to be most efficient.
|
||||
This method should NOT save; rather it is the save() that triggers this function.
|
||||
Its main purpose is to allow to plug-in a save handler and oob handlers.
|
||||
"""
|
||||
if raw:
|
||||
return
|
||||
if update_fields:
|
||||
# this is a list of strings at this point. We want field objects
|
||||
update_fields = (_GA(_GA(instance, "_meta"), "get_field_by_name")(field)[0] for field in update_fields)
|
||||
else:
|
||||
# meta.fields are already field objects; get them all
|
||||
update_fields = _GA(_GA(instance, "_meta"), "fields")
|
||||
for field in update_fields:
|
||||
fieldname = field.name
|
||||
handlername = "_at_%s_postsave" % fieldname
|
||||
handler = _GA(instance, handlername) if handlername in _GA(sender, '__dict__') else None
|
||||
if callable(handler):
|
||||
handler()
|
||||
trackerhandler = _GA(instance, "_trackerhandler") if "_trackerhandler" in _GA(instance, '__dict__') else None
|
||||
if trackerhandler:
|
||||
trackerhandler.update(fieldname, new_value)
|
||||
#if hid:
|
||||
# # update cache
|
||||
# _FIELD_CACHE[hid] = new_value
|
||||
trackerhandler.update(fieldname, _GA(instance, fieldname))
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Attr cache - caching the attribute objects related to a given object to
|
||||
|
|
@ -125,63 +133,64 @@ def field_pre_save(sender, instance=None, update_fields=None, raw=False, **kwarg
|
|||
# to any property).
|
||||
#------------------------------------------------------------
|
||||
|
||||
# connected to m2m_changed signal in respective model class
|
||||
def post_attr_update(sender, **kwargs):
|
||||
"Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
|
||||
obj = kwargs['instance']
|
||||
model = kwargs['model']
|
||||
action = kwargs['action']
|
||||
if kwargs['reverse']:
|
||||
# the reverse relation changed (the Attribute itself was acted on)
|
||||
pass
|
||||
else:
|
||||
# forward relation changed (the Object holding the Attribute m2m field)
|
||||
if not kwargs["pk_set"]:
|
||||
return
|
||||
if action == "post_add":
|
||||
# cache all added objects
|
||||
for attr_id in kwargs["pk_set"]:
|
||||
attr_obj = model.objects.get(pk=attr_id)
|
||||
set_attr_cache(obj, _GA(attr_obj, "db_key"), attr_obj)
|
||||
elif action == "post_remove":
|
||||
# obj.db_attributes.remove(attr) was called
|
||||
for attr_id in kwargs["pk_set"]:
|
||||
attr_obj = model.objects.get(pk=attr_id)
|
||||
del_attr_cache(obj, _GA(attr_obj, "db_key"))
|
||||
attr_obj.delete()
|
||||
elif action == "post_clear":
|
||||
# obj.db_attributes.clear() was called
|
||||
clear_obj_attr_cache(obj)
|
||||
|
||||
# access methods
|
||||
|
||||
def get_attr_cache(obj, attrname):
|
||||
"Called by getting attribute"
|
||||
hid = hashid(obj, "-%s" % attrname)
|
||||
return _ATTR_CACHE.get(hid, None)
|
||||
|
||||
def set_attr_cache(obj, attrname, attrobj):
|
||||
"Set the attr cache manually; this can be used to update"
|
||||
global _ATTR_CACHE
|
||||
hid = hashid(obj, "-%s" % attrname)
|
||||
_ATTR_CACHE[hid] = attrobj
|
||||
|
||||
def del_attr_cache(obj, attrname):
|
||||
"Del attribute cache"
|
||||
global _ATTR_CACHE
|
||||
hid = hashid(obj, "-%s" % attrname)
|
||||
if hid in _ATTR_CACHE:
|
||||
del _ATTR_CACHE[hid]
|
||||
|
||||
def flush_attr_cache():
|
||||
"Clear attribute cache"
|
||||
global _ATTR_CACHE
|
||||
_ATTR_CACHE = {}
|
||||
|
||||
def clear_obj_attr_cache(obj):
|
||||
global _ATTR_CACHE
|
||||
hid = hashid(obj)
|
||||
_ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)}
|
||||
## connected to m2m_changed signal in respective model class
|
||||
#def post_attr_update(sender, **kwargs):
|
||||
# "Called when the many2many relation changes (NOT when updating the value of an Attribute!)"
|
||||
# obj = kwargs['instance']
|
||||
# model = kwargs['model']
|
||||
# action = kwargs['action']
|
||||
# if kwargs['reverse']:
|
||||
# # the reverse relation changed (the Attribute itself was acted on)
|
||||
# pass
|
||||
# else:
|
||||
# # forward relation changed (the Object holding the Attribute m2m field)
|
||||
# if not kwargs["pk_set"]:
|
||||
# return
|
||||
# if action == "post_add":
|
||||
# # cache all added objects
|
||||
# for attr_id in kwargs["pk_set"]:
|
||||
# attr_obj = model.objects.get(pk=attr_id)
|
||||
# set_attr_cache(obj, _GA(attr_obj, "db_key"), attr_obj)
|
||||
# elif action == "post_remove":
|
||||
# # obj.db_attributes.remove(attr) was called
|
||||
# for attr_id in kwargs["pk_set"]:
|
||||
# attr_obj = model.objects.get(pk=attr_id)
|
||||
# del_attr_cache(obj, _GA(attr_obj, "db_key"))
|
||||
# attr_obj.delete()
|
||||
# elif action == "post_clear":
|
||||
# # obj.db_attributes.clear() was called
|
||||
# clear_obj_attr_cache(obj)
|
||||
#
|
||||
#
|
||||
## attr cache - this is only left as deprecated cache
|
||||
#
|
||||
#def get_attr_cache(obj, attrname):
|
||||
# "Called by getting attribute"
|
||||
# hid = hashid(obj, "-%s" % attrname)
|
||||
# return _ATTR_CACHE.get(hid, None)
|
||||
#
|
||||
#def set_attr_cache(obj, attrname, attrobj):
|
||||
# "Set the attr cache manually; this can be used to update"
|
||||
# global _ATTR_CACHE
|
||||
# hid = hashid(obj, "-%s" % attrname)
|
||||
# _ATTR_CACHE[hid] = attrobj
|
||||
#
|
||||
#def del_attr_cache(obj, attrname):
|
||||
# "Del attribute cache"
|
||||
# global _ATTR_CACHE
|
||||
# hid = hashid(obj, "-%s" % attrname)
|
||||
# if hid in _ATTR_CACHE:
|
||||
# del _ATTR_CACHE[hid]
|
||||
#
|
||||
#def flush_attr_cache():
|
||||
# "Clear attribute cache"
|
||||
# global _ATTR_CACHE
|
||||
# _ATTR_CACHE = {}
|
||||
#
|
||||
#def clear_obj_attr_cache(obj):
|
||||
# global _ATTR_CACHE
|
||||
# hid = hashid(obj)
|
||||
# _ATTR_CACHE = {key:value for key, value in _ATTR_CACHE if not key.startswith(hid)}
|
||||
|
||||
#------------------------------------------------------------
|
||||
# Property cache - this is a generic cache for properties stored on models.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue