Index: django/db/models/sql/query.py
===================================================================
--- django/db/models/sql/query.py	(revisión: 9787)
+++ django/db/models/sql/query.py	(copia de trabajo)
@@ -22,6 +22,7 @@
 from django.core.exceptions import FieldError
 from datastructures import EmptyResultSet, Empty, MultiJoin
 from constants import *
+from django.core.cache import cache
 
 try:
     set
@@ -90,6 +91,9 @@
         self.extra_params = ()
         self.extra_order_by = ()
 
+        # Cached queryset atribute. None means no cached
+        self.cache_timeout = None
+
     def __str__(self):
         """
         Returns the query as a string of SQL with the parameter values
@@ -190,6 +194,7 @@
         obj.extra_where = self.extra_where
         obj.extra_params = self.extra_params
         obj.extra_order_by = self.extra_order_by
+        obj.cache_timeout = self.cache_timeout
         if self.filter_is_sticky and self.used_aliases:
             obj.used_aliases = self.used_aliases.copy()
         else:
@@ -237,7 +242,26 @@
         """
         resolve_columns = hasattr(self, 'resolve_columns')
         fields = None
-        for rows in self.execute_sql(MULTI):
+        if self.cache_timeout is not None:
+            # Check cache for stored objects from an exactly equal query
+            k = str(self)
+            try:
+                import hashlib
+            except ImportError:
+                import sha
+                k = sha.new(k).hexdigest()
+            else:
+                k = hashlib.sha1(k).hexdigest()
+
+            if cache.has_key(k) and cache.get(k):
+                sql_result = cache.get(k, [])
+            else:
+                cache.set(k, [i for i in self.execute_sql(MULTI)], self.cache_timeout)
+                sql_result = cache.get(k, [])
+        else:
+            sql_result = self.execute_sql(MULTI)
+
+        for rows in sql_result:
             for row in rows:
                 if resolve_columns:
                     if fields is None:
Index: django/db/models/manager.py
===================================================================
--- django/db/models/manager.py	(revisión: 9787)
+++ django/db/models/manager.py	(copia de trabajo)
@@ -140,6 +140,9 @@
     def reverse(self, *args, **kwargs):
         return self.get_query_set().reverse(*args, **kwargs)
 
+    def cache(self, timeout=20):
+        return self.get_query_set().cache(timeout=timeout)
+        
     def _insert(self, values, **kwargs):
         return insert_query(self.model, values, **kwargs)
 
Index: django/db/models/query.py
===================================================================
--- django/db/models/query.py	(revisión: 9787)
+++ django/db/models/query.py	(copia de trabajo)
@@ -640,6 +640,16 @@
         clone.query.standard_ordering = not clone.query.standard_ordering
         return clone
 
+    def cache(self, timeout=20):
+        """
+        Forces the current queryset to check if a exact equal query has been
+        stored in the cache. The expiration time is the seconds in 'timeout'
+        variable.
+        """
+        clone = self._clone()
+        clone.query.cache_timeout = timeout
+        return clone
+
     ###################
     # PRIVATE METHODS #
     ###################
