diff --git a/evennia/objects/models.py b/evennia/objects/models.py index e34ee2da1d..12fb92ef63 100644 --- a/evennia/objects/models.py +++ b/evennia/objects/models.py @@ -22,7 +22,7 @@ from django.core.exceptions import ObjectDoesNotExist from evennia.typeclasses.models import TypedObject from evennia.objects.manager import ObjectDBManager from evennia.utils import logger -from evennia.utils.utils import (make_iter, dbref, lazy_property, calledby) +from evennia.utils.utils import (make_iter, dbref, lazy_property) class ContentsHandler(object): @@ -51,10 +51,8 @@ class ContentsHandler(object): Re-initialize the content cache """ - #print "__init__", self.obj, calledby() self._pkcache.update(dict((obj.pk, None) for obj in ObjectDB.objects.filter(db_location=self.obj) if obj.pk)) - #print "init contentscache: self._pkcache:", self.obj, self._pkcache, id(self._pkcache), id(self) def get(self, exclude=None): """ @@ -70,15 +68,12 @@ class ContentsHandler(object): if exclude: pks = [pk for pk in self._pkcache if pk not in [excl.pk for excl in make_iter(exclude)]] else: - #print calledby() - #print "get: self._pkcache", self.obj, self._pkcache, id(self._pkcache), id(self) pks = self._pkcache try: return [self._idcache[pk] for pk in pks] except KeyError, err: # this can happen if the idmapper cache was cleared for an object # in the contents cache. If so we need to re-initialize and try again. - #print "content_cache.get keyerror:", err, self._pkcache, self._idcache self.init() try: return [self._idcache[pk] for pk in pks] @@ -96,7 +91,6 @@ class ContentsHandler(object): """ self._pkcache[obj.pk] = None - #print "add self._pkcache:", self.obj, obj, obj.pk, self._pkcache def remove(self, obj): """ @@ -107,7 +101,6 @@ class ContentsHandler(object): """ self._pkcache.pop(obj.pk, None) - #print "remove self._pkcache", self.obj, obj, obj.pk, self._pkcache def clear(self): """ @@ -116,7 +109,6 @@ class ContentsHandler(object): """ self._pkcache = {} self.init() - #print "clear _pkcache", self.obj, self._pkcache #------------------------------------------------------------ # @@ -272,12 +264,10 @@ class ObjectDB(TypedObject): # remove the safe flag del self._safe_contents_update - #print "location_set:", self.key, old_location, self.db_location # update the contents cache if old_location: old_location.contents_cache.remove(self) if self.db_location: - #print "cache add:", self.db_location, self self.db_location.contents_cache.add(self) except RuntimeError: diff --git a/evennia/typeclasses/models.py b/evennia/typeclasses/models.py index 2acadccca5..afbe576163 100644 --- a/evennia/typeclasses/models.py +++ b/evennia/typeclasses/models.py @@ -386,6 +386,14 @@ class TypedObject(SharedMemoryModel): False, don't flush and expect this object to handle the flushing on its own. + Notes: + The default implementation relies on being able to clear + Django's Foreignkey cache on objects not affected by the + flush (notably objects with an NAttribute stored). We rely + on this cache being stored on the format "__cache". + If Django were to change this name internally, we need to + update here (unlikely, but marking just in case). + """ if self.nattributes.all(): # we can't flush this object if we have non-persistent @@ -393,6 +401,12 @@ class TypedObject(SharedMemoryModel): # we try to flush as many references as we can. self.attributes.reset_cache() self.tags.reset_cache() + # flush caches for all related fields + for field in self._meta.fields: + name = "_%s_cache" % field.name + if field.is_relation and name in self.__dict__: + # a foreignkey - remove its cache + del self.__dict__[name] return False # a normal flush return True diff --git a/evennia/utils/idmapper/models.py b/evennia/utils/idmapper/models.py index cb00fb6fc5..b74a05eb43 100644 --- a/evennia/utils/idmapper/models.py +++ b/evennia/utils/idmapper/models.py @@ -321,8 +321,6 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): else: cls.__dbclass__.__instance_cache__ = dict((key, obj) for key, obj in cls.__dbclass__.__instance_cache__.items() if not obj.at_idmapper_flush()) - for ins in cls.__dbclass__.__instance_cache__.itervalues(): - ins.refresh_from_db() #flush_instance_cache = classmethod(flush_instance_cache) # per-instance methods @@ -349,8 +347,6 @@ class SharedMemoryModel(with_metaclass(SharedMemoryModelBase, Model)): if pk: if force or self.at_idmapper_flush(): self.__class__.__dbclass__.__instance_cache__.pop(pk, None) - else: - self.refresh_from_db() def delete(self, *args, **kwargs): """