=== modified file 'django/db/models/base.py'
--- django/db/models/base.py	2007-02-08 05:26:44 +0000
+++ django/db/models/base.py	2007-02-09 20:04:27 +0000
@@ -14,6 +14,7 @@
 from django.utils.functional import curry
 from django.conf import settings
 from itertools import izip
+from weakref import WeakValueDictionary
 import types
 import sys
 import os
@@ -71,6 +72,21 @@
         # registered version.
         return get_model(new_class._meta.app_label, name, False)
 
+    def __call__(cls, *args, **kwargs):
+        if cls._meta.has_auto_field:
+            key = cls._get_cache_key(args, kwargs)
+            if key is not None:
+                obj = cls.__instance_cache__.get(key)
+                if obj is None:
+                    obj = super(ModelBase, cls).__call__(*args, **kwargs)
+                    cls.__instance_cache__[key] = obj
+            else:
+                obj = super(ModelBase, cls).__call__(*args, **kwargs)
+        else:
+            obj = super(ModelBase, cls).__call__(*args, **kwargs)
+        return obj
+
+
 class Model(object):
     __metaclass__ = ModelBase
 
@@ -89,6 +105,23 @@
     def __ne__(self, other):
         return not self.__eq__(other)
 
+    def _get_cache_key(cls, args, kwargs):
+        # this should be calculated *once*, but isn't atm
+        pk_position = cls._meta.fields.index(cls._meta.pk)
+        if len(args) > pk_position:
+            return args[pk_position]
+        pk = cls._meta.pk
+        if pk.name in kwargs:
+            return kwargs[pk.name]
+        elif pk.attname in kwargs:
+            return kwargs[pk.attname]
+        return None
+    _get_cache_key = classmethod(_get_cache_key)
+
+    def get_cached_instance(cls, id):
+        return cls.__instance_cache__.get(id)
+    get_cached_instance = classmethod(get_cached_instance)
+
     def __init__(self, *args, **kwargs):
         dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
         # there is a rather weird disparity here; if kwargs, it's set, then args overrides it.
@@ -185,6 +218,8 @@
         if hasattr(cls, 'get_absolute_url'):
             cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url)
 
+        cls.__instance_cache__ = WeakValueDictionary()
+
         dispatcher.send(signal=signals.class_prepared, sender=cls)
 
     _prepare = classmethod(_prepare)
@@ -241,6 +276,10 @@
                 setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column))
         transaction.commit_unless_managed()
 
+        # if we're a new instance that hasn't been written in; save ourself.
+        if self._meta.has_auto_field:
+            self.__instance_cache__.setdefault(pk_val, self)
+
         # Run any post-save hooks.
         dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self)
 

=== modified file 'django/db/models/fields/related.py'
--- django/db/models/fields/related.py	2007-02-04 21:23:07 +0000
+++ django/db/models/fields/related.py	2007-02-09 11:52:52 +0000
@@ -163,12 +163,14 @@
                 if self.field.null:
                     return None
                 raise self.field.rel.to.DoesNotExist
-            other_field = self.field.rel.get_related_field()
-            if other_field.rel:
-                params = {'%s__pk' % self.field.rel.field_name: val}
-            else:
-                params = {'%s__exact' % self.field.rel.field_name: val}
-            rel_obj = self.field.rel.to._default_manager.get(**params)
+            rel_obj = self.field.rel.to.get_cached_instance(val)
+            if rel_obj is None:
+                other_field = self.field.rel.get_related_field()
+                if other_field.rel:
+                    params = {'%s__pk' % self.field.rel.field_name: val}
+                else:
+                    params = {'%s__exact' % self.field.rel.field_name: val}
+                rel_obj = self.field.rel.to._default_manager.get(**params)
             setattr(instance, cache_name, rel_obj)
             return rel_obj
 

