diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index ea14281..45e0a99 100644
|
a
|
b
|
class TemplateView(TemplateResponseMixin, View):
|
| 117 | 117 | """ |
| 118 | 118 | def get_context_data(self, **kwargs): |
| 119 | 119 | return { |
| 120 | | 'params': kwargs |
| | 120 | 'params': kwargs, |
| | 121 | 'view': self |
| 121 | 122 | } |
| 122 | 123 | |
| 123 | 124 | 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
|
b
|
class SingleObjectMixin(object):
|
| 87 | 87 | |
| 88 | 88 | def get_context_data(self, **kwargs): |
| 89 | 89 | context = kwargs |
| | 90 | if 'view' not in context: |
| | 91 | context['view'] = self |
| 90 | 92 | context_object_name = self.get_context_object_name(self.object) |
| 91 | 93 | if context_object_name: |
| 92 | 94 | 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
|
b
|
class FormMixin(object):
|
| 46 | 46 | return kwargs |
| 47 | 47 | |
| 48 | 48 | def get_context_data(self, **kwargs): |
| | 49 | if 'view' not in kwargs: |
| | 50 | kwargs['view'] = self |
| 49 | 51 | return kwargs |
| 50 | 52 | |
| 51 | 53 | def get_success_url(self): |
| … |
… |
class ModelFormMixin(FormMixin, SingleObjectMixin):
|
| 90 | 92 | |
| 91 | 93 | def get_form_kwargs(self): |
| 92 | 94 | """ |
| 93 | | Returns the keyword arguments for instanciating the form. |
| | 95 | Returns the keyword arguments for instantiating the form. |
| 94 | 96 | """ |
| 95 | 97 | kwargs = super(ModelFormMixin, self).get_form_kwargs() |
| 96 | 98 | kwargs.update({'instance': self.object}) |
| … |
… |
class ModelFormMixin(FormMixin, SingleObjectMixin):
|
| 114 | 116 | |
| 115 | 117 | def get_context_data(self, **kwargs): |
| 116 | 118 | context = kwargs |
| | 119 | if 'view' not in context: |
| | 120 | context['view'] = self |
| 117 | 121 | if self.object: |
| 118 | 122 | context['object'] = self.object |
| 119 | 123 | 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
|
b
|
class MultipleObjectMixin(object):
|
| 94 | 94 | 'paginator': paginator, |
| 95 | 95 | 'page_obj': page, |
| 96 | 96 | 'is_paginated': is_paginated, |
| 97 | | 'object_list': queryset |
| | 97 | 'object_list': queryset, |
| | 98 | 'view': self |
| 98 | 99 | } |
| 99 | 100 | else: |
| 100 | 101 | context = { |
| 101 | 102 | 'paginator': None, |
| 102 | 103 | 'page_obj': None, |
| 103 | 104 | 'is_paginated': False, |
| 104 | | 'object_list': queryset |
| | 105 | 'object_list': queryset, |
| | 106 | 'view': self |
| 105 | 107 | } |
| 106 | 108 | context.update(kwargs) |
| 107 | 109 | 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
|
b
|
View
|
| 879 | 879 | The default implementation returns ``HttpResponseNotAllowed`` with list |
| 880 | 880 | of allowed methods in plain text. |
| 881 | 881 | |
| | 882 | **Context** |
| | 883 | |
| | 884 | .. versionadded:: 1.4 |
| | 885 | |
| | 886 | * ``view``: The template context of all class-based generic views will |
| | 887 | include a ``view`` variable that points to the ``View`` instance. |
| | 888 | |
| | 889 | .. admonition:: Use ``alters_data`` where appropriate |
| | 890 | |
| | 891 | Note that having the view instance in the template context may expose |
| | 892 | potentially hazardous methods to template authors. To prevent methods |
| | 893 | like this from being called in the template, set ``alters_data=True`` |
| | 894 | on those methods. For more information, the documention on |
| | 895 | :ref:`rendering a template context <start-alters-data-description>`. |
| | 896 | |
| 882 | 897 | TemplateView |
| 883 | 898 | ~~~~~~~~~~~~ |
| 884 | 899 | .. class:: TemplateView() |
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index 2b7d354..6bae4ef 100644
|
a
|
b
|
straight lookups. Here are some things to keep in mind:
|
| 195 | 195 | * A variable can only be called if it has no required arguments. Otherwise, |
| 196 | 196 | the system will return an empty string. |
| 197 | 197 | |
| | 198 | .. _start-alters-data-description: |
| | 199 | |
| 198 | 200 | * Obviously, there can be side effects when calling some variables, and |
| 199 | 201 | it'd be either foolish or a security hole to allow the template system |
| 200 | 202 | to access them. |
diff --git a/tests/regressiontests/generic_views/base.py b/tests/regressiontests/generic_views/base.py
index d9debb6..1e03577 100644
|
a
|
b
|
class TemplateViewTest(TestCase):
|
| 209 | 209 | self.assertEqual(response.status_code, 200) |
| 210 | 210 | self.assertEqual(response.context['params'], {'foo': 'bar'}) |
| 211 | 211 | |
| | 212 | def test_view_in_template_context(self): |
| | 213 | """ |
| | 214 | A generic template view includes the 'view' in the context. |
| | 215 | """ |
| | 216 | response = self.client.get('/template/simple/bar/') |
| | 217 | self.assertEqual(response.status_code, 200) |
| | 218 | self.assertTrue(isinstance(response.context['view'], View)) |
| | 219 | |
| 212 | 220 | def test_extra_template_params(self): |
| 213 | 221 | """ |
| 214 | 222 | 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
|
b
|
from __future__ import absolute_import
|
| 2 | 2 | |
| 3 | 3 | from django.core.exceptions import ImproperlyConfigured |
| 4 | 4 | from django.test import TestCase |
| | 5 | from django.views.generic.base import View |
| 5 | 6 | |
| 6 | 7 | from .models import Artist, Author, Page |
| 7 | 8 | |
| … |
… |
class DetailViewTest(TestCase):
|
| 10 | 11 | fixtures = ['generic-views-test-data.json'] |
| 11 | 12 | urls = 'regressiontests.generic_views.urls' |
| 12 | 13 | |
| | 14 | def test_view_in_template_context(self): |
| | 15 | res = self.client.get('/detail/obj/') |
| | 16 | self.assertTrue(isinstance(res.context['view'], View)) |
| | 17 | |
| 13 | 18 | def test_simple_object(self): |
| 14 | 19 | res = self.client.get('/detail/obj/') |
| 15 | 20 | 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
|
b
|
from django.core.urlresolvers import reverse
|
| 5 | 5 | from django import forms |
| 6 | 6 | from django.test import TestCase |
| 7 | 7 | from django.utils.unittest import expectedFailure |
| | 8 | from django.views.generic.base import View |
| 8 | 9 | |
| 9 | 10 | from . import views |
| 10 | 11 | from .models import Artist, Author |
| … |
… |
class CreateViewTests(TestCase):
|
| 92 | 93 | self.assertEqual(res.status_code, 302) |
| 93 | 94 | self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/') |
| 94 | 95 | |
| | 96 | def test_create_view_in_context(self): |
| | 97 | res = self.client.get('/edit/authors/create/') |
| | 98 | self.assertEqual(res.status_code, 200) |
| | 99 | self.assertTrue(isinstance(res.context['view'], View)) |
| | 100 | |
| | 101 | |
| 95 | 102 | class UpdateViewTests(TestCase): |
| 96 | 103 | urls = 'regressiontests.generic_views.urls' |
| 97 | 104 | |
| … |
… |
class UpdateViewTests(TestCase):
|
| 224 | 231 | self.assertRedirects(res, 'http://testserver/list/authors/') |
| 225 | 232 | self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>']) |
| 226 | 233 | |
| | 234 | def test_update_view_in_context(self): |
| | 235 | a = Author.objects.create( |
| | 236 | name='Randall Munroe', |
| | 237 | slug='randall-munroe', |
| | 238 | ) |
| | 239 | res = self.client.get('/edit/author/%d/update/' % a.pk) |
| | 240 | self.assertEqual(res.status_code, 200) |
| | 241 | self.assertTrue(isinstance(res.context['view'], View)) |
| | 242 | |
| | 243 | |
| 227 | 244 | class DeleteViewTests(TestCase): |
| 228 | 245 | urls = 'regressiontests.generic_views.urls' |
| 229 | 246 | |
diff --git a/tests/regressiontests/generic_views/list.py b/tests/regressiontests/generic_views/list.py
index 9ad00ed..d707b06 100644
|
a
|
b
|
from __future__ import absolute_import
|
| 2 | 2 | |
| 3 | 3 | from django.core.exceptions import ImproperlyConfigured |
| 4 | 4 | from django.test import TestCase |
| | 5 | from django.views.generic.base import View |
| 5 | 6 | |
| 6 | 7 | from .models import Author, Artist |
| 7 | 8 | |
| … |
… |
class ListViewTests(TestCase):
|
| 159 | 160 | def test_missing_items(self): |
| 160 | 161 | self.assertRaises(ImproperlyConfigured, self.client.get, '/list/authors/invalid/') |
| 161 | 162 | |
| | 163 | def test_view_in_context(self): |
| | 164 | res = self.client.get('/list/authors/') |
| | 165 | self.assertEqual(res.status_code, 200) |
| | 166 | self.assertTrue(isinstance(res.context['view'], View)) |
| | 167 | |
| 162 | 168 | def _make_authors(self, n): |
| 163 | 169 | Author.objects.all().delete() |
| 164 | 170 | for i in range(n): |