Index: docs/generic_views.txt
===================================================================
--- docs/generic_views.txt	(revision 7720)
+++ docs/generic_views.txt	(working copy)
@@ -66,10 +66,7 @@
 to pass any auxiliary information you wish to the view. The values in the
 ``extra_context`` dictionary can be either functions (or other callables) or
 other objects. Functions are evaluated just before they are passed to the
-template. However, note that QuerySets retrieve and cache their data when they
-are first evaluated, so if you want to pass in a QuerySet via
-``extra_context`` that is always fresh you need to wrap it in a function or
-lambda that returns the QuerySet.
+template. QuerySets will be cloned so that they are always fresh and up to date.
 
 .. _database API docs: ../db-api/
 
Index: django/views/generic/common.py
===================================================================
--- django/views/generic/common.py	(revision 0)
+++ django/views/generic/common.py	(revision 0)
@@ -0,0 +1,10 @@
+from django.db.models.query import QuerySet
+
+def _add_extra_context(c, extra_context):
+    for key, value in extra_context.items():
+        if callable(value):
+            c[key] = value()
+        elif isinstance(value, QuerySet):
+            c[key] = value._clone()
+        else:
+            c[key] = value
Index: django/views/generic/create_update.py
===================================================================
--- django/views/generic/create_update.py	(revision 7720)
+++ django/views/generic/create_update.py	(working copy)
@@ -7,6 +7,7 @@
 from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
 from django.utils.translation import ugettext
+from django.views.generic.common import _add_extra_context
 
 def create_object(request, model, template_name=None,
         template_loader=loader, extra_context=None, post_save_redirect=None,
@@ -63,11 +64,7 @@
     c = RequestContext(request, {
         'form': form,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c))
 
 def update_object(request, model, object_id=None, slug=None,
@@ -136,11 +133,7 @@
         'form': form,
         template_object_name: object,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     response = HttpResponse(t.render(c))
     populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
     return response
@@ -190,11 +183,7 @@
         c = RequestContext(request, {
             template_object_name: object,
         }, context_processors)
-        for key, value in extra_context.items():
-            if callable(value):
-                c[key] = value()
-            else:
-                c[key] = value
+        _add_extra_context(c, extra_context)
         response = HttpResponse(t.render(c))
         populate_xheaders(request, response, model, getattr(object, object._meta.pk.attname))
         return response
Index: django/views/generic/date_based.py
===================================================================
--- django/views/generic/date_based.py	(revision 7720)
+++ django/views/generic/date_based.py	(working copy)
@@ -6,6 +6,7 @@
 from django.core.xheaders import populate_xheaders
 from django.db.models.fields import DateTimeField
 from django.http import Http404, HttpResponse
+from django.views.generic.common import _add_extra_context
 
 def archive_index(request, queryset, date_field, num_latest=15,
         template_name=None, template_loader=loader,
@@ -41,11 +42,7 @@
         'date_list' : date_list,
         template_object_name : latest,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c), mimetype=mimetype)
 
 def archive_year(request, year, queryset, date_field, template_name=None,
@@ -89,11 +86,7 @@
         'year': year,
         '%s_list' % template_object_name: object_list,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c), mimetype=mimetype)
 
 def archive_month(request, year, month, queryset, date_field,
@@ -155,11 +148,7 @@
         'next_month': next_month,
         'previous_month': first_day - datetime.timedelta(days=1),
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c), mimetype=mimetype)
 
 def archive_week(request, year, week, queryset, date_field,
@@ -203,11 +192,7 @@
         '%s_list' % template_object_name: object_list,
         'week': date,
     })
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c), mimetype=mimetype)
 
 def archive_day(request, year, month, day, queryset, date_field,
@@ -267,11 +252,7 @@
         'previous_day': date - datetime.timedelta(days=1),
         'next_day': next_day,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     return HttpResponse(t.render(c), mimetype=mimetype)
 
 def archive_today(request, **kwargs):
@@ -336,11 +317,7 @@
     c = RequestContext(request, {
         template_object_name: obj,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     response = HttpResponse(t.render(c), mimetype=mimetype)
     populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
     return response
Index: django/views/generic/list_detail.py
===================================================================
--- django/views/generic/list_detail.py	(revision 7720)
+++ django/views/generic/list_detail.py	(working copy)
@@ -3,6 +3,7 @@
 from django.core.xheaders import populate_xheaders
 from django.core.paginator import QuerySetPaginator, InvalidPage
 from django.core.exceptions import ObjectDoesNotExist
+from django.views.generic.common import _add_extra_context
 
 def object_list(request, queryset, paginate_by=None, page=None,
         allow_empty=True, template_name=None, template_loader=loader,
@@ -89,11 +90,7 @@
         }, context_processors)
         if not allow_empty and len(queryset) == 0:
             raise Http404
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     if not template_name:
         model = queryset.model
         template_name = "%s/%s_list.html" % (model._meta.app_label, model._meta.object_name.lower())
@@ -135,11 +132,7 @@
     c = RequestContext(request, {
         template_object_name: obj,
     }, context_processors)
-    for key, value in extra_context.items():
-        if callable(value):
-            c[key] = value()
-        else:
-            c[key] = value
+    _add_extra_context(c, extra_context)
     response = HttpResponse(t.render(c), mimetype=mimetype)
     populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
     return response
Index: django/views/generic/simple.py
===================================================================
--- django/views/generic/simple.py	(revision 7720)
+++ django/views/generic/simple.py	(working copy)
@@ -1,6 +1,7 @@
 from django.shortcuts import render_to_response
 from django.template import loader, RequestContext
 from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseGone
+from django.views.generic.common import _add_extra_context
 
 def direct_to_template(request, template, extra_context=None, mimetype=None, **kwargs):
     """
@@ -9,11 +10,7 @@
     """
     if extra_context is None: extra_context = {}
     dictionary = {'params': kwargs}
-    for key, value in extra_context.items():
-        if callable(value):
-            dictionary[key] = value()
-        else:
-            dictionary[key] = value
+    _add_extra_context(dictionary, extra_context)
     c = RequestContext(request, dictionary)
     t = loader.get_template(template)
     return HttpResponse(t.render(c), mimetype=mimetype)
