Fixed #16744 -- Class based view should have the view object in the context
Updated the most recent patch from @claudep to apply again and updated the documentation location.
This commit is contained in:
parent
547b181046
commit
58683e9c82
|
@ -18,6 +18,8 @@ class ContextMixin(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
if 'view' not in kwargs:
|
||||||
|
kwargs['view'] = self
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,20 @@ ContextMixin
|
||||||
|
|
||||||
.. method:: get_context_data(**kwargs)
|
.. method:: get_context_data(**kwargs)
|
||||||
|
|
||||||
Returns a dictionary representing the template context. The
|
Returns a dictionary representing the template context. The keyword
|
||||||
keyword arguments provided will make up the returned context.
|
arguments provided will make up the returned context.
|
||||||
|
|
||||||
|
The template context of all class-based generic views 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, read
|
||||||
|
the documentation on :ref:`rendering a template context
|
||||||
|
<alters-data-description>`.
|
||||||
|
|
||||||
TemplateResponseMixin
|
TemplateResponseMixin
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
@ -198,6 +198,8 @@ straight lookups. Here are some things to keep in mind:
|
||||||
* A variable can only be called if it has no required arguments. Otherwise,
|
* A variable can only be called if it has no required arguments. Otherwise,
|
||||||
the system will return an empty string.
|
the system will return an empty string.
|
||||||
|
|
||||||
|
.. _alters-data-description:
|
||||||
|
|
||||||
* Obviously, there can be side effects when calling some variables, and
|
* 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
|
it'd be either foolish or a security hole to allow the template system
|
||||||
to access them.
|
to access them.
|
||||||
|
|
|
@ -84,6 +84,12 @@ By passing ``False`` using this argument it is now possible to retreive the
|
||||||
:class:`ContentType <django.contrib.contenttypes.models.ContentType>`
|
:class:`ContentType <django.contrib.contenttypes.models.ContentType>`
|
||||||
associated with proxy models.
|
associated with proxy models.
|
||||||
|
|
||||||
|
New ``view`` variable in class-based views context
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
In all :doc:`generic class-based views </topics/class-based-views/index>`
|
||||||
|
(or any class-based view inheriting from ``ContextMixin``), the context dictionary
|
||||||
|
contains a ``view`` variable that points to the ``View`` instance.
|
||||||
|
|
||||||
Minor features
|
Minor features
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,7 @@ class TemplateViewTest(TestCase):
|
||||||
response = self.client.get('/template/simple/bar/')
|
response = self.client.get('/template/simple/bar/')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.context['params'], {'foo': 'bar'})
|
self.assertEqual(response.context['params'], {'foo': 'bar'})
|
||||||
|
self.assertTrue(isinstance(response.context['view'], View))
|
||||||
|
|
||||||
def test_extra_template_params(self):
|
def test_extra_template_params(self):
|
||||||
"""
|
"""
|
||||||
|
@ -285,6 +286,7 @@ class TemplateViewTest(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.context['params'], {'foo': 'bar'})
|
self.assertEqual(response.context['params'], {'foo': 'bar'})
|
||||||
self.assertEqual(response.context['key'], 'value')
|
self.assertEqual(response.context['key'], 'value')
|
||||||
|
self.assertTrue(isinstance(response.context['view'], View))
|
||||||
|
|
||||||
def test_cached_views(self):
|
def test_cached_views(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.views.generic.base import View
|
||||||
|
|
||||||
from .models import Artist, Author, Page
|
from .models import Artist, Author, Page
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ class DetailViewTest(TestCase):
|
||||||
res = self.client.get('/detail/obj/')
|
res = self.client.get('/detail/obj/')
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertEqual(res.context['object'], {'foo': 'bar'})
|
self.assertEqual(res.context['object'], {'foo': 'bar'})
|
||||||
|
self.assertTrue(isinstance(res.context['view'], View))
|
||||||
self.assertTemplateUsed(res, 'generic_views/detail.html')
|
self.assertTemplateUsed(res, 'generic_views/detail.html')
|
||||||
|
|
||||||
def test_detail_by_pk(self):
|
def test_detail_by_pk(self):
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.unittest import expectedFailure
|
from django.utils.unittest import expectedFailure
|
||||||
|
from django.views.generic.base import View
|
||||||
from django.views.generic.edit import FormMixin
|
from django.views.generic.edit import FormMixin
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
@ -31,6 +32,7 @@ class CreateViewTests(TestCase):
|
||||||
res = self.client.get('/edit/authors/create/')
|
res = self.client.get('/edit/authors/create/')
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
|
self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
|
||||||
|
self.assertTrue(isinstance(res.context['view'], View))
|
||||||
self.assertFalse('object' in res.context)
|
self.assertFalse('object' in res.context)
|
||||||
self.assertFalse('author' in res.context)
|
self.assertFalse('author' in res.context)
|
||||||
self.assertTemplateUsed(res, 'generic_views/author_form.html')
|
self.assertTemplateUsed(res, 'generic_views/author_form.html')
|
||||||
|
@ -101,6 +103,7 @@ class CreateViewTests(TestCase):
|
||||||
self.assertEqual(res.status_code, 302)
|
self.assertEqual(res.status_code, 302)
|
||||||
self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
|
self.assertRedirects(res, 'http://testserver/accounts/login/?next=/edit/authors/create/restricted/')
|
||||||
|
|
||||||
|
|
||||||
class UpdateViewTests(TestCase):
|
class UpdateViewTests(TestCase):
|
||||||
urls = 'regressiontests.generic_views.urls'
|
urls = 'regressiontests.generic_views.urls'
|
||||||
|
|
||||||
|
@ -226,6 +229,7 @@ class UpdateViewTests(TestCase):
|
||||||
res = self.client.get('/edit/author/update/')
|
res = self.client.get('/edit/author/update/')
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
|
self.assertTrue(isinstance(res.context['form'], forms.ModelForm))
|
||||||
|
self.assertTrue(isinstance(res.context['view'], View))
|
||||||
self.assertEqual(res.context['object'], Author.objects.get(pk=a.pk))
|
self.assertEqual(res.context['object'], Author.objects.get(pk=a.pk))
|
||||||
self.assertEqual(res.context['author'], Author.objects.get(pk=a.pk))
|
self.assertEqual(res.context['author'], Author.objects.get(pk=a.pk))
|
||||||
self.assertTemplateUsed(res, 'generic_views/author_form.html')
|
self.assertTemplateUsed(res, 'generic_views/author_form.html')
|
||||||
|
@ -237,6 +241,7 @@ class UpdateViewTests(TestCase):
|
||||||
self.assertRedirects(res, 'http://testserver/list/authors/')
|
self.assertRedirects(res, 'http://testserver/list/authors/')
|
||||||
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
|
self.assertQuerysetEqual(Author.objects.all(), ['<Author: Randall Munroe (xkcd)>'])
|
||||||
|
|
||||||
|
|
||||||
class DeleteViewTests(TestCase):
|
class DeleteViewTests(TestCase):
|
||||||
urls = 'regressiontests.generic_views.urls'
|
urls = 'regressiontests.generic_views.urls'
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import absolute_import
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.views.generic.base import View
|
||||||
|
|
||||||
from .models import Author, Artist
|
from .models import Author, Artist
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ class ListViewTests(TestCase):
|
||||||
self.assertEqual(res.status_code, 200)
|
self.assertEqual(res.status_code, 200)
|
||||||
self.assertTemplateUsed(res, 'generic_views/author_list.html')
|
self.assertTemplateUsed(res, 'generic_views/author_list.html')
|
||||||
self.assertEqual(list(res.context['object_list']), list(Author.objects.all()))
|
self.assertEqual(list(res.context['object_list']), list(Author.objects.all()))
|
||||||
|
self.assertTrue(isinstance(res.context['view'], View))
|
||||||
self.assertIs(res.context['author_list'], res.context['object_list'])
|
self.assertIs(res.context['author_list'], res.context['object_list'])
|
||||||
self.assertIsNone(res.context['paginator'])
|
self.assertIsNone(res.context['paginator'])
|
||||||
self.assertIsNone(res.context['page_obj'])
|
self.assertIsNone(res.context['page_obj'])
|
||||||
|
|
Loading…
Reference in New Issue