diff --git a/contrib/tutorial_world/mob.py b/contrib/tutorial_world/mob.py index bbdb4c561d..e4a221ce1f 100644 --- a/contrib/tutorial_world/mob.py +++ b/contrib/tutorial_world/mob.py @@ -104,7 +104,6 @@ class AttackTimer(Script): "Called every self.interval seconds." if self.obj.db.inactive: return - #print "attack timer: at_repeat", self.dbobj.id, self.ndb.twisted_task, # id(self.ndb.twisted_task) if self.obj.db.roam_mode: self.obj.roam() @@ -382,4 +381,4 @@ class Enemy(Mob): string = self.db.respawn_text if not string: string = "%s fades into existence from out of thin air. It's looking pissed." % self.key - self.location.msg_contents(string) \ No newline at end of file + self.location.msg_contents(string) diff --git a/game/gamesrc/objects/examples/object.py b/game/gamesrc/objects/examples/object.py index 57dbc7024a..51cbc4d21b 100644 --- a/game/gamesrc/objects/examples/object.py +++ b/game/gamesrc/objects/examples/object.py @@ -44,10 +44,7 @@ class Object(DefaultObject): aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Object, read-only) - link to database model. dbobj.typeclass points back to this class - typeclass (Object, read-only) - this links back to this class as an - identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings diff --git a/game/gamesrc/objects/examples/player.py b/game/gamesrc/objects/examples/player.py index 339e0994ef..f587a71f25 100644 --- a/game/gamesrc/objects/examples/player.py +++ b/game/gamesrc/objects/examples/player.py @@ -39,8 +39,6 @@ class Player(DefaultPlayer): name (string)- wrapper for user.username aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Player, read-only) - link to database model. dbobj.typeclass points back to this class - typeclass (Player, read-only) - this links back to this class as an identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings diff --git a/game/gamesrc/scripts/examples/script.py b/game/gamesrc/scripts/examples/script.py index 05b670fb95..7e310f5a11 100644 --- a/game/gamesrc/scripts/examples/script.py +++ b/game/gamesrc/scripts/examples/script.py @@ -35,10 +35,6 @@ class ExampleScript(BaseScript): aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Object, read-only) - link to database model. dbobj.typeclass - points back to this class - typeclass (Object, read-only) - this links back to this class as an - identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings diff --git a/src/commands/default/building.py b/src/commands/default/building.py index b1fcdd3c78..837864ffff 100644 --- a/src/commands/default/building.py +++ b/src/commands/default/building.py @@ -150,7 +150,7 @@ class CmdSetObjAlias(MuxCommand): old_aliases = obj.aliases.all() if old_aliases: caller.msg("Cleared aliases from %s: %s" % (obj.key, ", ".join(old_aliases))) - obj.dbobj.aliases.clear() + obj.aliases.clear() else: caller.msg("No aliases to clear.") return @@ -447,10 +447,10 @@ class CmdCreate(ObjManipCommand): continue if aliases: string = "You create a new %s: %s (aliases: %s)." - string = string % (obj.typeclass.typename, obj.name, ", ".join(aliases)) + string = string % (obj.typename, obj.name, ", ".join(aliases)) else: string = "You create a new %s: %s." - string = string % (obj.typeclass.typename, obj.name) + string = string % (obj.typename, obj.name) # set a default desc if not obj.db.desc: obj.db.desc = "You see nothing special." @@ -1401,7 +1401,7 @@ class CmdTypeclass(MuxCommand): # current one instead. if hasattr(obj, "typeclass"): string = "%s's current typeclass is '%s' (%s)." % (obj.name, - obj.typeclass.typename, obj.typeclass.path) + obj.typename, obj.path) else: string = "%s is not a typed object." % obj.name caller.msg(string) @@ -1427,7 +1427,7 @@ class CmdTypeclass(MuxCommand): ok = obj.swap_typeclass(typeclass, clean_attributes=reset) if ok: if is_same: - string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.typeclass.path) + string = "%s updated its existing typeclass (%s).\n" % (obj.name, obj.path) else: string = "%s changed typeclass from %s to %s.\n" % (obj.name, old_typeclass_path, @@ -1677,7 +1677,7 @@ class CmdExamine(ObjManipCommand): string += "\n{wPlayer Perms{n: %s" % (", ".join(perms)) if obj.player.attributes.has("_quell"): string += " {r(quelled){n" - string += "\n{wTypeclass{n: %s (%s)" % (obj.typeclass.typename, + string += "\n{wTypeclass{n: %s (%s)" % (obj.typename, obj.typeclass_path) if hasattr(obj, "location"): string += "\n{wLocation{n: %s" % obj.location @@ -1928,7 +1928,7 @@ class CmdFind(MuxCommand): else: result=result[0] string += "\n{g %s(%s) - %s{n" % (result.key, result.dbref, - result.typeclass.path) + result.path) else: # Not a player/dbref search but a wider search; build a queryset. # Searchs for key and aliases @@ -1946,7 +1946,7 @@ class CmdFind(MuxCommand): if nresults: # convert result to typeclasses. - results = [result.typeclass for result in results] + results = [result for result in results] if "room" in switches: results = [obj for obj in results if inherits_from(obj, ROOM_TYPECLASS)] if "exit" in switches: diff --git a/src/commands/default/comms.py b/src/commands/default/comms.py index a6f2d0d40a..2f67e661b3 100644 --- a/src/commands/default/comms.py +++ b/src/commands/default/comms.py @@ -792,7 +792,7 @@ class CmdIRC2Chan(MuxCommand): if 'list' in self.switches: # show all connections - ircbots = [bot.typeclass for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")] + ircbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")] if ircbots: from src.utils.evtable import EvTable table = EvTable("{wdbid{n", "{wbotname{n", "{wev-channel{n", "{wirc-channel{n", maxwidth=78) @@ -842,7 +842,7 @@ class CmdIRC2Chan(MuxCommand): bot = PlayerDB.objects.filter(username__iexact=botname) if bot: # re-use an existing bot - bot = bot[0].typeclass + bot = bot[0] if not bot.is_bot: self.msg("Player '%s' already exists and is not a bot." % botname) return @@ -901,7 +901,7 @@ class CmdRSS2Chan(MuxCommand): if 'list' in self.switches: # show all connections - rssbots = [bot.typeclass for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")] + rssbots = [bot for bot in PlayerDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")] if rssbots: from src.utils.evtable import EvTable table = EvTable("{wdbid{n", "{wupdate rate{n", "{wev-channel", "{wRSS feed URL{n", border="cells", maxwidth=78) @@ -938,7 +938,7 @@ class CmdRSS2Chan(MuxCommand): bot = PlayerDB.objects.filter(username__iexact=botname) if bot: # re-use existing bot - bot = bot[0].typeclass + bot = bot[0] if not bot.is_bot: self.msg("Player '%s' already exists and is not a bot." % botname) return diff --git a/src/commands/default/general.py b/src/commands/default/general.py index 74303bb229..7ffcd8e142 100644 --- a/src/commands/default/general.py +++ b/src/commands/default/general.py @@ -155,7 +155,6 @@ class CmdNick(MuxCommand): string = "" for switch in switches: oldnick = caller.nicks.get(key=nick, category=switch) - #oldnick = Nick.objects.filter(db_obj=caller.dbobj, db_nick__iexact=nick, db_type__iexact=switch) if not real: # removal of nick if oldnick: diff --git a/src/comms/managers.py b/src/comms/managers.py index cdab16ae22..4a2b08f114 100644 --- a/src/comms/managers.py +++ b/src/comms/managers.py @@ -300,7 +300,7 @@ class ChannelDBManager(TypedObjectManager): """ Return all channels a given player is subscribed to """ - return player.dbobj.subscription_set.all() + return player.__dbclass__.subscription_set.all() @returns_typeclass_list def channel_search(self, ostring, exact=True): diff --git a/src/comms/models.py b/src/comms/models.py index 21d4369b04..6c274e540e 100644 --- a/src/comms/models.py +++ b/src/comms/models.py @@ -223,8 +223,9 @@ class Msg(SharedMemoryModel): def __channels_set(self, value): """ Setter. Allows for self.channels = value. - Requires a channel to be added.""" - for val in (v.dbobj for v in make_iter(value) if v): + Requires a channel to be added. + """ + for val in (v for v in make_iter(value) if v): self.db_receivers_channels.add(val) #@channels.deleter diff --git a/src/locks/lockfuncs.py b/src/locks/lockfuncs.py index 461dc6daf6..d5d76cf60b 100644 --- a/src/locks/lockfuncs.py +++ b/src/locks/lockfuncs.py @@ -125,7 +125,7 @@ def self(accessing_obj, accessed_obj, *args, **kwargs): This can be used to lock specifically only to the same object that the lock is defined on. """ - return accessing_obj.typeclass == accessed_obj.typeclass + return accessing_obj == accessed_obj def perm(accessing_obj, accessed_obj, *args, **kwargs): diff --git a/src/objects/admin.py b/src/objects/admin.py index 078700cc13..2072404167 100644 --- a/src/objects/admin.py +++ b/src/objects/admin.py @@ -119,7 +119,6 @@ class ObjectDBAdmin(admin.ModelAdmin): obj.save() if not change: # adding a new object - obj = obj.typeclass obj.basetype_setup() obj.basetype_posthook_setup() obj.at_object_creation() diff --git a/src/objects/manager.py b/src/objects/manager.py index 2be80ac064..eb530febb3 100644 --- a/src/objects/manager.py +++ b/src/objects/manager.py @@ -156,8 +156,6 @@ class ObjectDBManager(TypedObjectManager): if isinstance(property_name, basestring): if not property_name.startswith('db_'): property_name = "db_%s" % property_name - if hasattr(property_value, 'dbobj'): - property_value = property_value.dbobj querykwargs = {property_name:property_value} cand_restriction = candidates != None and Q(pk__in=[_GA(obj, "id") for obj in make_iter(candidates) if obj]) or Q() type_restriction = typeclasses and Q(db_typeclass_path__in=make_iter(typeclasses)) or Q() @@ -299,7 +297,7 @@ class ObjectDBManager(TypedObjectManager): if candidates: # Convenience check to make sure candidates are really dbobjs - candidates = [cand.dbobj for cand in make_iter(candidates) if cand] + candidates = [cand for cand in make_iter(candidates) if cand] if typeclass: candidates = [cand for cand in candidates if _GA(cand, "db_typeclass_path") in typeclass] @@ -309,7 +307,7 @@ class ObjectDBManager(TypedObjectManager): # Easiest case - dbref matching (always exact) dbref_match = self.dbref_search(dbref) if dbref_match: - if not candidates or dbref_match.dbobj in candidates: + if not candidates or dbref_match in candidates: return [dbref_match] else: return [] @@ -402,7 +400,7 @@ class ObjectDBManager(TypedObjectManager): # copy over all scripts, if any for script in original_object.scripts.all(): - ScriptDB.objects.copy_script(script, new_obj=new_object.dbobj) + ScriptDB.objects.copy_script(script, new_obj=new_object) return new_object diff --git a/src/objects/objects.py b/src/objects/objects.py index 597a0fd7c9..60bdd6b943 100644 --- a/src/objects/objects.py +++ b/src/objects/objects.py @@ -115,10 +115,6 @@ class DefaultObject(ObjectDB): aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Object, read-only) - link to database model. dbobj.typeclass - points back to this class - typeclass (Object, read-only) - this links back to this class as an - identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings @@ -886,6 +882,16 @@ class DefaultObject(ObjectDB): if cdict.get("location"): cdict["location"].at_object_receive(self, None) self.at_after_move(None) + + if cdict.get("attributes"): + # this should be a dict of attrname:value + keys, values = cdict["attributes"].keys(), cdict["attributes"].values() + self.attributes.batch_add(keys, values) + if cdict.get("nattributes"): + # this should be a dict of nattrname:value + for key, value in cdict["nattributes"].items(): + self.nattributes.add(key, value) + del self._createdict self.basetype_posthook_setup() @@ -1437,8 +1443,8 @@ class DefaultExit(DefaultObject): "get:false()"])) # noone can pick up the exit # an exit should have a destination (this is replaced at creation time) - if self.dbobj.location: - self.destination = self.dbobj.location + if self.location: + self.destination = self.location def at_cmdset_get(self, **kwargs): """ @@ -1452,7 +1458,7 @@ class DefaultExit(DefaultObject): if "force_init" in kwargs or not self.cmdset.has_cmdset("_exitset", must_be_default=True): # we are resetting, or no exit-cmdset was set. Create one dynamically. - self.cmdset.add_default(self.create_exit_cmdset(self.dbobj), permanent=False) + self.cmdset.add_default(self.create_exit_cmdset(self), permanent=False) # this and other hooks are what usually can be modified safely. diff --git a/src/players/admin.py b/src/players/admin.py index d01646cd65..a456ed9899 100644 --- a/src/players/admin.py +++ b/src/players/admin.py @@ -204,7 +204,7 @@ class PlayerDBAdmin(BaseUserAdmin): obj.save() if not change: #calling hooks for new player - ply = obj.typeclass + ply = obj ply.basetype_setup() ply.at_player_creation() diff --git a/src/players/bots.py b/src/players/bots.py index 2298758154..1190c577b7 100644 --- a/src/players/bots.py +++ b/src/players/bots.py @@ -76,7 +76,7 @@ class CmdBotListen(Command): key = "bot_data_in" def func(self): "Relay to typeclass" - self.obj.typeclass.execute_cmd(self.args.strip(), sessid=self.sessid) + self.obj.execute_cmd(self.args.strip(), sessid=self.sessid) class BotCmdSet(CmdSet): "Holds the BotListen command" @@ -196,9 +196,9 @@ class IRCBot(Bot): # cache channel lookup self.ndb.ev_channel = self.db.ev_channel if "from_channel" in kwargs and text and self.ndb.ev_channel.dbid == kwargs["from_channel"]: - if "from_obj" not in kwargs or kwargs["from_obj"] != [self.dbobj.id]: + if "from_obj" not in kwargs or kwargs["from_obj"] != [self.id]: text = "bot_data_out %s" % text - self.dbobj.msg(text=text) + self.msg(text=text) def execute_cmd(self, text=None, sessid=None): """ @@ -209,7 +209,7 @@ class IRCBot(Bot): # cache channel lookup self.ndb.ev_channel = self.db.ev_channel if self.ndb.ev_channel: - self.ndb.ev_channel.msg(text, senders=self.dbobj.id) + self.ndb.ev_channel.msg(text, senders=self.id) # RSS @@ -258,7 +258,7 @@ class RSSBot(Bot): # cache channel lookup self.ndb.ev_channel = self.db.ev_channel if self.ndb.ev_channel: - self.ndb.ev_channel.msg(text, senders=self.dbobj.id) + self.ndb.ev_channel.msg(text, senders=self.id) class IMC2Bot(Bot): """ @@ -318,9 +318,9 @@ class IMC2Bot(Bot): # cache channel lookup self.ndb.ev_channel = self.db.ev_channel if "from_channel" in kwargs and text and self.ndb.ev_channel.dbid == kwargs["from_channel"]: - if "from_obj" not in kwargs or kwargs["from_obj"] != [self.dbobj.id]: + if "from_obj" not in kwargs or kwargs["from_obj"] != [self.id]: text = "bot_data_out %s" % text - self.dbobj.msg(text=text) + self.msg(text=text) def execute_cmd(self, text=None, sessid=None): """ @@ -330,5 +330,5 @@ class IMC2Bot(Bot): # cache channel lookup self.ndb.ev_channel = self.db.ev_channel if self.ndb.ev_channel: - self.ndb.ev_channel.msg(text, senders=self.dbobj.id) + self.ndb.ev_channel.msg(text, senders=self.id) diff --git a/src/players/player.py b/src/players/player.py index 67fe1872ce..4926b2f796 100644 --- a/src/players/player.py +++ b/src/players/player.py @@ -55,10 +55,6 @@ class DefaultPlayer(PlayerDB): aliases (list of strings) - aliases to the object. Will be saved to database as AliasDB entries but returned as strings. dbref (int, read-only) - unique #id-number. Also "id" can be used. - dbobj (Player, read-only) - link to database model. dbobj.typeclass - points back to this class - typeclass (Player, read-only) - this links back to this class as an - identified only. Use self.swap_typeclass() to switch. date_created (string) - time stamp of object creation permissions (list of strings) - list of permission strings diff --git a/src/scripts/scripthandler.py b/src/scripts/scripthandler.py index 796d9564ea..429397d88c 100644 --- a/src/scripts/scripthandler.py +++ b/src/scripts/scripthandler.py @@ -58,7 +58,7 @@ class ScriptHandler(object): definition) autostart - start the script upon adding it """ - if self.obj.dbobj.__class__.__name__ == "PlayerDB": + if self.obj.__class__.__name__ == "PlayerDB": # we add to a Player, not an Object script = create.create_script(scriptclass, key=key, player=self.obj, autostart=autostart) diff --git a/src/scripts/tickerhandler.py b/src/scripts/tickerhandler.py index cf3421a9ba..86234575c2 100644 --- a/src/scripts/tickerhandler.py +++ b/src/scripts/tickerhandler.py @@ -202,19 +202,10 @@ class TickerHandler(object): is a boolean True if obj was a database object, False otherwise. """ - try: - obj = obj.typeclass - except AttributeError: - pass - dbobj = None - try: - dbobj = obj.dbobj - except AttributeError: - pass - isdb = True - if dbobj: + if hasattr(obj, "db_key"): # create a store_key using the database representation - objkey = pack_dbobj(dbobj) + objkey = pack_dbobj(obj) + isdb = True else: # non-db object, look for a property "key" on it, otherwise # use its memory location. diff --git a/src/server/oobhandler.py b/src/server/oobhandler.py index 1dc4aca882..423840576b 100644 --- a/src/server/oobhandler.py +++ b/src/server/oobhandler.py @@ -83,10 +83,6 @@ class TrackerHandler(object): This is initiated and stored on the object as a property _trackerhandler. """ - try: - obj = obj.dbobj - except AttributeError: - pass self.obj = obj self.ntrackers = 0 # initiate store only with valid on-object fieldnames @@ -194,10 +190,6 @@ class ReportAttributeTracker(TrackerBase): def update(self, new_value, *args, **kwargs): "Called by cache when attribute's db_value field updates" - try: - new_value = new_value.dbobj - except AttributeError: - new_value = to_str(new_value, force_string=True) kwargs[self.attrname] = new_value # this is a wrapper call for sending oob data back to session self.oobhandler.msg(self.sessid, "report", *args, **kwargs) @@ -282,11 +274,6 @@ class OOBHandler(object): named as propname, this will be used as the property name when assigning the OOB to obj, otherwise tracker_key is used as the property name. """ - try: - obj = obj.dbobj - except AttributeError: - pass - if not "_trackerhandler" in _GA(obj, "__dict__"): # assign trackerhandler to object _SA(obj, "_trackerhandler", TrackerHandler(obj)) @@ -305,10 +292,6 @@ class OOBHandler(object): Remove the OOB from obj. If oob implements an at_delete hook, this will be called with args, kwargs """ - try: - obj = obj.dbobj - except AttributeError: - pass try: # call at_remove hook on the trackerclass _GA(obj, "_trackerhandler").remove(propname, trackerclass, *args, **kwargs) @@ -348,10 +331,6 @@ class OOBHandler(object): Object and name in a way the Attribute expects. """ # get the attribute object if we can - try: - attrobj = obj.dbobj - except AttributeError: - pass attrobj = obj.attributes.get(attr_name, return_obj=True) #print "track_attribute attrobj:", attrobj, id(attrobj) if attrobj: @@ -361,10 +340,6 @@ class OOBHandler(object): """ Shortcut for deactivating tracking for a given attribute. """ - try: - obj = obj.dbobj - except AttributeError: - pass attrobj = obj.attributes.get(attr_name, return_obj=True) if attrobj: self._untrack(attrobj, sessid, "db_value", trackerclass, attr_name) diff --git a/src/typeclasses/attributes.py b/src/typeclasses/attributes.py index 38783400d6..ce06327ee8 100644 --- a/src/typeclasses/attributes.py +++ b/src/typeclasses/attributes.py @@ -75,7 +75,7 @@ class Attribute(SharedMemoryModel): db_model = models.CharField( 'model', max_length=32, db_index=True, blank=True, null=True, help_text="Which model of object this attribute is attached to (A " - "natural key like objects.dbobject). You should not change " + "natural key like 'objects.dbobject'). You should not change " "this value unless you know what you are doing.") # subclass of Attribute (None or nick) db_attrtype = models.CharField( diff --git a/src/utils/dbserialize.py b/src/utils/dbserialize.py index bc4d292951..143e3c7f9d 100644 --- a/src/utils/dbserialize.py +++ b/src/utils/dbserialize.py @@ -42,7 +42,6 @@ _GA = object.__getattribute__ _SA = object.__setattr__ _FROM_MODEL_MAP = None _TO_MODEL_MAP = None -_TO_TYPECLASS = lambda o: hasattr(o, 'typeclass') and o.typeclass or o _IS_PACKED_DBOBJ = lambda o: type(o) == tuple and len(o) == 4 and o[0] == '__packed_dbobj__' if uses_database("mysql") and ServerConfig.objects.get_mysql_db_version() < '5.6.4': # mysql <5.6.4 don't support millisecond precision @@ -214,7 +213,7 @@ def pack_dbobj(item): ("__packed_dbobj__", key, creation_time, id) """ _init_globals() - obj = hasattr(item, 'dbobj') and item.dbobj or item + obj = item natural_key = _FROM_MODEL_MAP[hasattr(obj, "id") and hasattr(obj, "db_date_created") and hasattr(obj, '__dbclass__') and obj.__dbclass__.__name__.lower()] # build the internal representation as a tuple @@ -232,16 +231,12 @@ def unpack_dbobj(item): """ _init_globals() try: - obj = item[3] and _TO_TYPECLASS(_TO_MODEL_MAP[item[1]].objects.get(id=item[3])) + obj = item[3] and _TO_MODEL_MAP[item[1]].objects.get(id=item[3]) except ObjectDoesNotExist: return None # even if we got back a match, check the sanity of the date (some # databases may 're-use' the id) - try: - dbobj = obj.dbobj - except AttributeError: - dbobj = obj - return _TO_DATESTRING(dbobj) == item[2] and obj or None + return _TO_DATESTRING(obj) == item[2] and obj or None # # Access methods diff --git a/src/utils/spawner.py b/src/utils/spawner.py index cddaab2743..659428a65d 100644 --- a/src/utils/spawner.py +++ b/src/utils/spawner.py @@ -137,33 +137,17 @@ def _batch_create_object(*objparams): #dbobjs = _ObjectDB.objects.bulk_create(dbobjs) objs = [] - for iobj, dbobj in enumerate(dbobjs): + for iobj, obj in enumerate(dbobjs): # call all setup hooks on each object objparam = objparams[iobj] - obj = dbobj.typeclass # this saves dbobj if not done already - obj.basetype_setup() - obj.at_object_creation() - - if objparam[1]: - # permissions - obj.permissions.add(objparam[1]) - if objparam[2]: - # locks - obj.locks.add(objparam[2]) - if objparam[3]: - # aliases - obj.aliases.add(objparam[3]) - if objparam[4]: - # nattributes - for key, value in objparam[4].items(): - obj.nattributes.add(key, value) - if objparam[5]: - # attributes - keys, values = objparam[5].keys(), objparam[5].values() - obj.attributes.batch_add(keys, values) - - obj.basetype_posthook_setup() - objs.append(obj) + # setup + obj._createdict = {"pernmissions": objparam[1], + "locks": objparam[2], + "aliases": objparam[3], + "attributes": objparam[4], + "nattributes": objparam[5]} + # this triggers all hooks + obj.save() return objs diff --git a/src/utils/utils.py b/src/utils/utils.py index 89c54bab80..017bbcd90d 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -584,7 +584,6 @@ def clean_object_caches(obj): #print "recaching:", obj if not obj: return - obj = hasattr(obj, "dbobj") and obj.dbobj or obj # contents cache try: _SA(obj, "_contents_cache", None)