diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index fcdc7c7..431cb1e 100644
--- a/django/views/generic/base.py
+++ b/django/views/generic/base.py
@@ -8,6 +8,16 @@ from django.utils.decorators import classonlymethod
 logger = getLogger('django.request')
 
 
+class ContextMixin(object):
+    """
+    A default context mixin that passes the keyword arguments received by
+    get_context_data as the template context.
+    """
+
+    def get_context_data(self, **kwargs):
+        return kwargs
+
+
 class View(object):
     """
     Intentionally simple parent class for all views. Only implements
@@ -110,17 +120,17 @@ class TemplateResponseMixin(object):
             return [self.template_name]
 
 
-class TemplateView(TemplateResponseMixin, View):
+class TemplateView(TemplateResponseMixin, ContextMixin, View):
     """
-    A view that renders a template.
+    A view that renders a template.  This view is different from all the others
+    insofar as it also passes ``kwargs`` as ``params`` to the template context
+    (this functionality has been deprecated).
     """
     def get_context_data(self, **kwargs):
-        return {
-            'params': kwargs
-        }
+        return super(TemplateView, self).get_context_data(**kwargs)
 
     def get(self, request, *args, **kwargs):
-        context = self.get_context_data(**kwargs)
+        context = self.get_context_data(params=kwargs)
         return self.render_to_response(context)
 
 
diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py
index 5f5f959..e5c3e5b 100644
--- a/django/views/generic/dates.py
+++ b/django/views/generic/dates.py
@@ -217,16 +217,6 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
 
         return date_list
 
-    def get_context_data(self, **kwargs):
-        """
-        Get the context. Must return a Context (or subclass) instance.
-        """
-        items = kwargs.pop('object_list')
-        context = super(BaseDateListView, self).get_context_data(object_list=items)
-        context.update(kwargs)
-        return context
-
-
 class BaseArchiveIndexView(BaseDateListView):
     """
     Base class for archives of date-based items.
diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py
index b9278bb..a2adb15 100644
--- a/django/views/generic/detail.py
+++ b/django/views/generic/detail.py
@@ -2,10 +2,10 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
 from django.http import Http404
 from django.utils.encoding import smart_str
 from django.utils.translation import ugettext as _
-from django.views.generic.base import TemplateResponseMixin, View
+from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
 
 
-class SingleObjectMixin(object):
+class SingleObjectMixin(ContextMixin):
     """
     Provides the ability to retrieve a single object for further manipulation.
     """
@@ -86,11 +86,12 @@ class SingleObjectMixin(object):
             return None
 
     def get_context_data(self, **kwargs):
-        context = kwargs
+        context = {}
         context_object_name = self.get_context_object_name(self.object)
         if context_object_name:
             context[context_object_name] = self.object
-        return context
+        context.update(kwargs)
+        return super(SingleObjectMixin, self).get_context_data(**context)
 
 
 class BaseDetailView(SingleObjectMixin, View):
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
index d107e9a..1f488cb 100644
--- a/django/views/generic/edit.py
+++ b/django/views/generic/edit.py
@@ -1,12 +1,12 @@
 from django.forms import models as model_forms
 from django.core.exceptions import ImproperlyConfigured
 from django.http import HttpResponseRedirect
-from django.views.generic.base import TemplateResponseMixin, View
+from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
 from django.views.generic.detail import (SingleObjectMixin,
                         SingleObjectTemplateResponseMixin, BaseDetailView)
 
 
-class FormMixin(object):
+class FormMixin(ContextMixin):
     """
     A mixin that provides a way to show and handle a form in a request.
     """
@@ -45,9 +45,6 @@ class FormMixin(object):
             })
         return kwargs
 
-    def get_context_data(self, **kwargs):
-        return kwargs
-
     def get_success_url(self):
         if self.success_url:
             url = self.success_url
@@ -113,13 +110,14 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
         return super(ModelFormMixin, self).form_valid(form)
 
     def get_context_data(self, **kwargs):
-        context = kwargs
+        context = {}
         if self.object:
             context['object'] = self.object
             context_object_name = self.get_context_object_name(self.object)
             if context_object_name:
                 context[context_object_name] = self.object
-        return context
+        context.update(kwargs)
+        return super(ModelFormMixin, self).get_context_data(**context)
 
 
 class ProcessFormView(View):
diff --git a/django/views/generic/list.py b/django/views/generic/list.py
index 9797356..d4664c3 100644
--- a/django/views/generic/list.py
+++ b/django/views/generic/list.py
@@ -3,10 +3,10 @@ from django.core.exceptions import ImproperlyConfigured
 from django.http import Http404
 from django.utils.encoding import smart_str
 from django.utils.translation import ugettext as _
-from django.views.generic.base import TemplateResponseMixin, View
+from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
 
 
-class MultipleObjectMixin(object):
+class MultipleObjectMixin(ContextMixin):
     allow_empty = True
     queryset = None
     model = None
@@ -103,10 +103,10 @@ class MultipleObjectMixin(object):
                 'is_paginated': False,
                 'object_list': queryset
             }
-        context.update(kwargs)
         if context_object_name is not None:
             context[context_object_name] = queryset
-        return context
+        context.update(kwargs)
+        return super(MultipleObjectMixin, self).get_context_data(**context)
 
 
 class BaseListView(MultipleObjectMixin, View):
diff --git a/docs/topics/class-based-views.txt b/docs/topics/class-based-views.txt
index 8059ed1..e1e2618 100644
--- a/docs/topics/class-based-views.txt
+++ b/docs/topics/class-based-views.txt
@@ -270,6 +270,16 @@ more::
             context['book_list'] = Book.objects.all()
             return context
 
+.. note::
+
+    Generally, get_context_data will merge the context data of all parent classes
+    with those of the current class.  To preserve this behavior in your own classes
+    where you want to alter the context, you should be sure to call
+    get_context_data on the super class. When no two classes try to define the same
+    key, this will give the expected results. However if any class attempts to
+    override a key after parent classes have set it (after the call to super), any
+    children of that class will also need to explictly set it after super if they
+    want to be sure to override all parents.
 
 Viewing subsets of objects
 --------------------------
diff --git a/tests/regressiontests/generic_views/base.py b/tests/regressiontests/generic_views/base.py
index 6528dc6..e18ed2a 100644
--- a/tests/regressiontests/generic_views/base.py
+++ b/tests/regressiontests/generic_views/base.py
@@ -1,3 +1,5 @@
+from __future__ import absolute_import
+
 import time
 
 from django.core.exceptions import ImproperlyConfigured
@@ -6,6 +8,7 @@ from django.test import TestCase, RequestFactory
 from django.utils import unittest
 from django.views.generic import View, TemplateView, RedirectView
 
+from . import views
 
 class SimpleView(View):
     """
@@ -331,3 +334,19 @@ class RedirectViewTest(unittest.TestCase):
         # we can't use self.rf.get because it always sets QUERY_STRING
         response = RedirectView.as_view(url='/bar/')(self.rf.request(PATH_INFO='/foo/'))
         self.assertEqual(response.status_code, 301)
+
+
+class GetContextDataTest(unittest.TestCase):
+
+    def test_get_context_data_super(self):
+        test_view = views.CustomContextView()
+        context = test_view.get_context_data(kwarg_test='kwarg_value')
+
+        # the test_name key is inserted by the test classes parent
+        self.assertTrue('test_name' in context)
+        self.assertEqual(context['kwarg_test'], 'kwarg_value')
+        self.assertEqual(context['custom_key'], 'custom_value')
+
+        # test that kwarg overrides values assigned higher up
+        context = test_view.get_context_data(test_name='test_value')
+        self.assertEqual(context['test_name'], 'test_value')
diff --git a/tests/regressiontests/generic_views/tests.py b/tests/regressiontests/generic_views/tests.py
index 72aab03..c985ad3 100644
--- a/tests/regressiontests/generic_views/tests.py
+++ b/tests/regressiontests/generic_views/tests.py
@@ -1,6 +1,7 @@
 from __future__ import absolute_import
 
-from .base import ViewTest, TemplateViewTest, RedirectViewTest
+from .base import (ViewTest, TemplateViewTest, RedirectViewTest,
+    GetContextDataTest)
 from .dates import (ArchiveIndexViewTests, YearArchiveViewTests,
     MonthArchiveViewTests, WeekArchiveViewTests, DayArchiveViewTests,
     DateDetailViewTests)
diff --git a/tests/regressiontests/generic_views/views.py b/tests/regressiontests/generic_views/views.py
index 5ff9cf0..1e70ba4 100644
--- a/tests/regressiontests/generic_views/views.py
+++ b/tests/regressiontests/generic_views/views.py
@@ -14,10 +14,9 @@ class CustomTemplateView(generic.TemplateView):
     template_name = 'generic_views/about.html'
 
     def get_context_data(self, **kwargs):
-        return {
-            'params': kwargs,
-            'key': 'value'
-        }
+        context = super(CustomTemplateView, self).get_context_data(**kwargs)
+        context.update({'key': 'value'})
+        return context
 
 
 class ObjectDetail(generic.DetailView):
@@ -184,3 +183,18 @@ class BookDetailGetObjectCustomQueryset(BookDetail):
     def get_object(self, queryset=None):
         return super(BookDetailGetObjectCustomQueryset,self).get_object(
             queryset=Book.objects.filter(pk=2))
+
+class CustomContextView(generic.detail.SingleObjectMixin, generic.View):
+    model = Book
+    object = Book(name='dummy')
+
+    def get_object(self):
+        return Book(name="dummy")
+
+    def get_context_data(self, **kwargs):
+        context = {'custom_key': 'custom_value'}
+        context.update(kwargs)
+        return super(CustomContextView, self).get_context_data(**context)
+
+    def get_context_object_name(self, obj):
+        return "test_name"
