Code

Ticket #16744: 16744-2.diff

File 16744-2.diff, 7.9 KB (added by claudep, 2 years ago)

Updated patch

Line 
1diff --git a/django/views/generic/base.py b/django/views/generic/base.py
2index c32a58a..f1e786c 100644
3--- a/django/views/generic/base.py
4+++ b/django/views/generic/base.py
5@@ -15,6 +15,8 @@ class ContextMixin(object):
6     """
7 
8     def get_context_data(self, **kwargs):
9+        if 'view' not in kwargs:
10+            kwargs['view'] = self
11         return kwargs
12 
13 
14diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py
15index 1f488cb..ab27a89 100644
16--- a/django/views/generic/edit.py
17+++ b/django/views/generic/edit.py
18@@ -35,7 +35,7 @@ class FormMixin(ContextMixin):
19 
20     def get_form_kwargs(self):
21         """
22-        Returns the keyword arguments for instanciating the form.
23+        Returns the keyword arguments for instantiating the form.
24         """
25         kwargs = {'initial': self.get_initial()}
26         if self.request.method in ('POST', 'PUT'):
27diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
28index 5223aee..005f38f 100644
29--- a/docs/ref/class-based-views.txt
30+++ b/docs/ref/class-based-views.txt
31@@ -884,6 +884,22 @@ View
32         The default implementation returns ``HttpResponseNotAllowed`` with list
33         of allowed methods in plain text.
34 
35+    **Context**
36+
37+    .. versionadded:: 1.5
38+
39+    * ``view``: The template context of all class-based generic views include
40+      a ``view`` variable that points to the ``View`` instance.
41+
42+      .. admonition:: Use ``alters_data`` where appropriate
43+
44+          Note that having the view instance in the template context may expose
45+          potentially hazardous methods to template authors.  To prevent methods
46+          like this from being called in the template, set ``alters_data=True``
47+          on those methods.  For more information, read the documentation on
48+          :ref:`rendering a template context <alters-data-description>`.
49+
50+
51 TemplateView
52 ~~~~~~~~~~~~
53 .. class:: TemplateView()
54diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
55index 03fef1d..2bb20f9 100644
56--- a/docs/ref/templates/api.txt
57+++ b/docs/ref/templates/api.txt
58@@ -195,6 +195,8 @@ straight lookups. Here are some things to keep in mind:
59 * A variable can only be called if it has no required arguments. Otherwise,
60   the system will return an empty string.
61 
62+.. _alters-data-description:
63+
64 * Obviously, there can be side effects when calling some variables, and
65   it'd be either foolish or a security hole to allow the template system
66   to access them.
67diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
68index 84459f9..731ff02 100644
69--- a/docs/releases/1.5.txt
70+++ b/docs/releases/1.5.txt
71@@ -33,6 +33,12 @@ Django 1.5 does not run on Jython.
72 What's new in Django 1.5
73 ========================
74 
75+New ``view`` variable in class-based views context
76+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77+In all :doc:`generic class-based views </topics/class-based-views>`
78+(or any class-based view inheriting from ``ContextMixin``), the context dictionary
79+contains a ``view`` variable that points to the ``View`` instance.
80+
81 Backwards incompatible changes in 1.5
82 =====================================
83 
84diff --git a/tests/regressiontests/generic_views/base.py b/tests/regressiontests/generic_views/base.py
85index e18ed2a..af1f48c 100644
86--- a/tests/regressiontests/generic_views/base.py
87+++ b/tests/regressiontests/generic_views/base.py
88@@ -224,6 +224,7 @@ class TemplateViewTest(TestCase):
89         response = self.client.get('/template/simple/bar/')
90         self.assertEqual(response.status_code, 200)
91         self.assertEqual(response.context['params'], {'foo': 'bar'})
92+        self.assertTrue(isinstance(response.context['view'], View))
93 
94     def test_extra_template_params(self):
95         """
96@@ -233,6 +234,7 @@ class TemplateViewTest(TestCase):
97         self.assertEqual(response.status_code, 200)
98         self.assertEqual(response.context['params'], {'foo': 'bar'})
99         self.assertEqual(response.context['key'], 'value')
100+        self.assertTrue(isinstance(response.context['view'], View))
101 
102     def test_cached_views(self):
103         """
104diff --git a/tests/regressiontests/generic_views/detail.py b/tests/regressiontests/generic_views/detail.py
105index 0b5d873..24c73f3 100644
106--- a/tests/regressiontests/generic_views/detail.py
107+++ b/tests/regressiontests/generic_views/detail.py
108@@ -2,6 +2,7 @@ from __future__ import absolute_import
109 
110 from django.core.exceptions import ImproperlyConfigured
111 from django.test import TestCase
112+from django.views.generic.base import View
113 
114 from .models import Artist, Author, Page
115 
116@@ -14,6 +15,7 @@ class DetailViewTest(TestCase):
117         res = self.client.get('/detail/obj/')
118         self.assertEqual(res.status_code, 200)
119         self.assertEqual(res.context['object'], {'foo': 'bar'})
120+        self.assertTrue(isinstance(res.context['view'], View))
121         self.assertTemplateUsed(res, 'generic_views/detail.html')
122 
123     def test_detail_by_pk(self):
124diff --git a/tests/regressiontests/generic_views/edit.py b/tests/regressiontests/generic_views/edit.py
125index 651e14f..16f4da8 100644
126--- a/tests/regressiontests/generic_views/edit.py
127+++ b/tests/regressiontests/generic_views/edit.py
128@@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse
129 from django import forms
130 from django.test import TestCase
131 from django.utils.unittest import expectedFailure
132+from django.views.generic.base import View
133 from django.views.generic.edit import FormMixin
134 
135 from . import views
136@@ -31,6 +32,7 @@ class CreateViewTests(TestCase):
137         res = self.client.get('/edit/authors/create/')
138         self.assertEqual(res.status_code, 200)
139         self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
140+        self.assertTrue(isinstance(res.context['view'], View))
141         self.assertFalse('object' in res.context)
142         self.assertFalse('author' in res.context)
143         self.assertTemplateUsed(res, 'generic_views/author_form.html')
144@@ -101,6 +103,7 @@ class CreateViewTests(TestCase):
145         self.assertEqual(res.status_code, 302)
146         self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
147 
148+
149 class UpdateViewTests(TestCase):
150     urls = 'regressiontests.generic_views.urls'
151 
152@@ -226,6 +229,7 @@ class UpdateViewTests(TestCase):
153         res = self.client.get('/edit/author/update/')
154         self.assertEqual(res.status_code, 200)
155         self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
156+        self.assertTrue(isinstance(res.context['view'], View))
157         self.assertEqual(res.context['object'], Author.objects.get(pk=a.pk))
158         self.assertEqual(res.context['author'], Author.objects.get(pk=a.pk))
159         self.assertTemplateUsed(res, 'generic_views/author_form.html')
160@@ -237,6 +241,7 @@ class UpdateViewTests(TestCase):
161         self.assertRedirects(res, 'http://testserver/list/authors/')
162         self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
163 
164+
165 class DeleteViewTests(TestCase):
166     urls = 'regressiontests.generic_views.urls'
167 
168diff --git a/tests/regressiontests/generic_views/list.py b/tests/regressiontests/generic_views/list.py
169index 9ad00ed..47d6b18 100644
170--- a/tests/regressiontests/generic_views/list.py
171+++ b/tests/regressiontests/generic_views/list.py
172@@ -2,6 +2,7 @@ from __future__ import absolute_import
173 
174 from django.core.exceptions import ImproperlyConfigured
175 from django.test import TestCase
176+from django.views.generic.base import View
177 
178 from .models import Author, Artist
179 
180@@ -21,6 +22,7 @@ class ListViewTests(TestCase):
181         self.assertEqual(res.status_code, 200)
182         self.assertTemplateUsed(res, 'generic_views/author_list.html')
183         self.assertEqual(list(res.context['object_list']), list(Author.objects.all()))
184+        self.assertTrue(isinstance(res.context['view'], View))
185         self.assertIs(res.context['author_list'], res.context['object_list'])
186         self.assertIsNone(res.context['paginator'])
187         self.assertIsNone(res.context['page_obj'])