diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index ea14281..45e0a99 100644
--- a/django/views/generic/base.py
+++ b/django/views/generic/base.py
@@ -117,7 +117,8 @@ class TemplateView(TemplateResponseMixin, View):
     """
     def get_context_data(self, **kwargs):
         return {
-            'params': kwargs
+            'params': kwargs,
+            'view': self
         }
 
     def get(self, request, *args, **kwargs):
diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py
index ab21573..6e84cb5 100644
--- a/django/views/generic/detail.py
+++ b/django/views/generic/detail.py
@@ -87,6 +87,8 @@ class SingleObjectMixin(object):
 
     def get_context_data(self, **kwargs):
         context = kwargs
+        if 'view' not in context:
+            context['view'] = self
         context_object_name = self.get_context_object_name(self.object)
         if context_object_name:
             context[context_object_name] = self.object
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
index 3cade52..6c53e27 100644
--- a/django/views/generic/edit.py
+++ b/django/views/generic/edit.py
@@ -46,6 +46,8 @@ class FormMixin(object):
         return kwargs
 
     def get_context_data(self, **kwargs):
+        if 'view' not in kwargs:
+            kwargs['view'] = self
         return kwargs
 
     def get_success_url(self):
@@ -90,7 +92,7 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
 
     def get_form_kwargs(self):
         """
-        Returns the keyword arguments for instanciating the form.
+        Returns the keyword arguments for instantiating the form.
         """
         kwargs = super(ModelFormMixin, self).get_form_kwargs()
         kwargs.update({'instance': self.object})
@@ -114,6 +116,8 @@ class ModelFormMixin(FormMixin, SingleObjectMixin):
 
     def get_context_data(self, **kwargs):
         context = kwargs
+        if 'view' not in context:
+            context['view'] = self
         if self.object:
             context['object'] = self.object
             context_object_name = self.get_context_object_name(self.object)
diff --git a/django/views/generic/list.py b/django/views/generic/list.py
index 9797356..e04656a 100644
--- a/django/views/generic/list.py
+++ b/django/views/generic/list.py
@@ -94,14 +94,16 @@ class MultipleObjectMixin(object):
                 'paginator': paginator,
                 'page_obj': page,
                 'is_paginated': is_paginated,
-                'object_list': queryset
+                'object_list': queryset,
+                'view': self
             }
         else:
             context = {
                 'paginator': None,
                 'page_obj': None,
                 'is_paginated': False,
-                'object_list': queryset
+                'object_list': queryset,
+                'view': self
             }
         context.update(kwargs)
         if context_object_name is not None:
diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
index 692417e..a851bf8 100644
--- a/docs/ref/class-based-views.txt
+++ b/docs/ref/class-based-views.txt
@@ -879,6 +879,21 @@ View
         The default implementation returns ``HttpResponseNotAllowed`` with list
         of allowed methods in plain text.
 
+    **Context**
+
+    .. versionadded:: 1.4
+
+    * ``view``: The template context of all class-based generic views will
+      include a ``view`` variable that points to the ``View`` instance.
+
+      .. admonition:: Use ``alters_data`` where appropriate
+
+          Note that having the view instance in the template context may expose
+          potentially hazardous methods to template authors.  To prevent methods
+          like this from being called in the template, set ``alters_data=True``
+          on those methods.  For more information, the documention on
+          :ref:`rendering a template context <start-alters-data-description>`.
+
 TemplateView
 ~~~~~~~~~~~~
 .. class:: TemplateView()
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index 2b7d354..6bae4ef 100644
--- a/docs/ref/templates/api.txt
+++ b/docs/ref/templates/api.txt
@@ -195,6 +195,8 @@ straight lookups. Here are some things to keep in mind:
 * A variable can only be called if it has no required arguments. Otherwise,
   the system will return an empty string.
 
+.. _start-alters-data-description:
+
 * Obviously, there can be side effects when calling some variables, and
   it'd be either foolish or a security hole to allow the template system
   to access them.
diff --git a/tests/regressiontests/generic_views/base.py b/tests/regressiontests/generic_views/base.py
index d9debb6..1e03577 100644
--- a/tests/regressiontests/generic_views/base.py
+++ b/tests/regressiontests/generic_views/base.py
@@ -209,6 +209,14 @@ class TemplateViewTest(TestCase):
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.context['params'], {'foo': 'bar'})
 
+    def test_view_in_template_context(self):
+        """
+        A generic template view includes the 'view' in the context.
+        """
+        response = self.client.get('/template/simple/bar/')
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue(isinstance(response.context['view'], View))
+
     def test_extra_template_params(self):
         """
         A template view can be customized to return extra context.
diff --git a/tests/regressiontests/generic_views/detail.py b/tests/regressiontests/generic_views/detail.py
index 0b5d873..10d0dbd 100644
--- a/tests/regressiontests/generic_views/detail.py
+++ b/tests/regressiontests/generic_views/detail.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import
 
 from django.core.exceptions import ImproperlyConfigured
 from django.test import TestCase
+from django.views.generic.base import View
 
 from .models import Artist, Author, Page
 
@@ -10,6 +11,10 @@ class DetailViewTest(TestCase):
     fixtures = ['generic-views-test-data.json']
     urls = 'regressiontests.generic_views.urls'
 
+    def test_view_in_template_context(self):
+        res = self.client.get('/detail/obj/')
+        self.assertTrue(isinstance(res.context['view'], View))
+
     def test_simple_object(self):
         res = self.client.get('/detail/obj/')
         self.assertEqual(res.status_code, 200)
diff --git a/tests/regressiontests/generic_views/edit.py b/tests/regressiontests/generic_views/edit.py
index 182615a..060b41a 100644
--- a/tests/regressiontests/generic_views/edit.py
+++ b/tests/regressiontests/generic_views/edit.py
@@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse
 from django import forms
 from django.test import TestCase
 from django.utils.unittest import expectedFailure
+from django.views.generic.base import View
 
 from . import views
 from .models import Artist, Author
@@ -92,6 +93,12 @@ class CreateViewTests(TestCase):
         self.assertEqual(res.status_code, 302)
         self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
 
+    def test_create_view_in_context(self):
+        res = self.client.get('/edit/authors/create/')
+        self.assertEqual(res.status_code, 200)
+        self.assertTrue(isinstance(res.context['view'], View))
+
+
 class UpdateViewTests(TestCase):
     urls = 'regressiontests.generic_views.urls'
 
@@ -224,6 +231,16 @@ class UpdateViewTests(TestCase):
         self.assertRedirects(res, 'http://testserver/list/authors/')
         self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
 
+    def test_update_view_in_context(self):
+        a = Author.objects.create(
+            name='Randall Munroe',
+            slug='randall-munroe',
+        )
+        res = self.client.get('/edit/author/%d/update/' % a.pk)
+        self.assertEqual(res.status_code, 200)
+        self.assertTrue(isinstance(res.context['view'], View))
+
+
 class DeleteViewTests(TestCase):
     urls = 'regressiontests.generic_views.urls'
 
diff --git a/tests/regressiontests/generic_views/list.py b/tests/regressiontests/generic_views/list.py
index 9ad00ed..d707b06 100644
--- a/tests/regressiontests/generic_views/list.py
+++ b/tests/regressiontests/generic_views/list.py
@@ -2,6 +2,7 @@ from __future__ import absolute_import
 
 from django.core.exceptions import ImproperlyConfigured
 from django.test import TestCase
+from django.views.generic.base import View
 
 from .models import Author, Artist
 
@@ -159,6 +160,11 @@ class ListViewTests(TestCase):
     def test_missing_items(self):
         self.assertRaises(ImproperlyConfigured, self.client.get, '/list/authors/invalid/')
 
+    def test_view_in_context(self):
+        res = self.client.get('/list/authors/')
+        self.assertEqual(res.status_code, 200)
+        self.assertTrue(isinstance(res.context['view'], View))
+
     def _make_authors(self, n):
         Author.objects.all().delete()
         for i in range(n):
