summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCollin Anderson <cmawebsite@gmail.com>2014-12-27 02:16:53 -0500
committerLoic Bistuer <loic.bistuer@gmail.com>2015-01-17 22:09:10 +0700
commita420f83e7d2e446ca01ef7c13d30c2ef3e975e5c (patch)
treec3c6aed2cd6c160d2f75e2f6f3f9d8c0b08d8ce7
parent67235fd4ef1b006fc9cdb2fa20e7bb93b0edff4b (diff)
downloaddjango-a420f83e7d2e446ca01ef7c13d30c2ef3e975e5c.tar.gz
Fixed #24055 -- Keep reference to view class for resolve()
-rw-r--r--django/contrib/admin/options.py1
-rw-r--r--django/contrib/admin/sites.py1
-rw-r--r--django/views/generic/base.py2
-rw-r--r--docs/ref/class-based-views/base.txt5
-rw-r--r--docs/ref/contrib/admin/index.txt5
-rw-r--r--docs/releases/1.9.txt8
-rw-r--r--tests/admin_views/tests.py9
-rw-r--r--tests/generic_views/test_base.py10
-rw-r--r--tests/generic_views/urls.py3
9 files changed, 42 insertions, 2 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index fe657546a4..ab10952e3f 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -583,6 +583,7 @@ class ModelAdmin(BaseModelAdmin):
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
+ wrapper.model_admin = self
return update_wrapper(wrapper, view)
info = self.model._meta.app_label, self.model._meta.model_name
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index ab0ec1a837..54d1e2de7a 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -245,6 +245,7 @@ class AdminSite(object):
def wrap(view, cacheable=False):
def wrapper(*args, **kwargs):
return self.admin_view(view, cacheable)(*args, **kwargs)
+ wrapper.admin_site = self
return update_wrapper(wrapper, view)
# Admin-site-wide views.
diff --git a/django/views/generic/base.py b/django/views/generic/base.py
index 8a9b6baa44..e9aac357f4 100644
--- a/django/views/generic/base.py
+++ b/django/views/generic/base.py
@@ -69,6 +69,8 @@ class View(object):
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
+ view.view_class = cls
+ view.view_initkwargs = initkwargs
# take name and docstring from class
update_wrapper(view, cls, updated=())
diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt
index 523b39d0e2..2c90cd4893 100644
--- a/docs/ref/class-based-views/base.txt
+++ b/docs/ref/class-based-views/base.txt
@@ -65,6 +65,11 @@ View
response = MyView.as_view()(request)
+ .. versionadded:: 1.9
+
+ The returned view has ``view_class`` and ``view_initkwargs``
+ attributes.
+
.. method:: dispatch(request, *args, **kwargs)
The ``view`` part of the view -- the method that accepts a ``request``
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index bb72f3fe55..317d48f351 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -1490,6 +1490,11 @@ templates used by the :class:`ModelAdmin` views:
url(r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True))
+ .. versionadded:: 1.9
+
+ ``ModelAdmin`` views have ``model_admin`` attributes. Other
+ ``AdminSite`` views have ``admin_site`` attributes.
+
.. method:: ModelAdmin.get_form(request, obj=None, **kwargs)
Returns a :class:`~django.forms.ModelForm` class for use in the admin add
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index 80ad57c053..1ff4022c7d 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -33,7 +33,7 @@ Minor features
:mod:`django.contrib.admin`
^^^^^^^^^^^^^^^^^^^^^^^^^^^
-* ...
+* Admin views now have ``model_admin`` or ``admin_site`` attributes.
:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -108,6 +108,12 @@ Forms
* ...
+Generic Views
+^^^^^^^^^^^^^
+
+* Class based views generated using ``as_view()`` now have ``view_class``
+ and ``view_initkwargs`` attributes.
+
Internationalization
^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index 0c28ecc029..c41a348078 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -11,7 +11,7 @@ from django.core.checks import Error
from django.core.files import temp as tempfile
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import (NoReverseMatch,
- get_script_prefix, reverse, set_script_prefix)
+ get_script_prefix, resolve, reverse, set_script_prefix)
# Register auth models with the admin.
from django.contrib.auth import get_permission_codename
from django.contrib.admin import ModelAdmin
@@ -56,6 +56,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker,
ParentWithDependentChildren, Character, FieldOverridePost, Color2)
+from . import customadmin
from .admin import site, site2, CityAdmin
@@ -749,6 +750,12 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
with self.assertRaises(NoReverseMatch):
reverse('admin:app_list', args=('admin_views2',))
+ def test_resolve_admin_views(self):
+ index_match = resolve('/test_admin/admin4/')
+ list_match = resolve('/test_admin/admin4/auth/user/')
+ self.assertIs(index_match.func.admin_site, customadmin.simple_site)
+ self.assertIsInstance(list_match.func.model_admin, customadmin.CustomPwdTemplateUserAdmin)
+
def test_proxy_model_content_type_is_used_for_log_entries(self):
"""
Log entries for proxy models should have the proxy model's content
diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py
index d855a3829b..ce3a0f52d6 100644
--- a/tests/generic_views/test_base.py
+++ b/tests/generic_views/test_base.py
@@ -5,6 +5,7 @@ import unittest
import warnings
from django.core.exceptions import ImproperlyConfigured
+from django.core.urlresolvers import resolve
from django.http import HttpResponse
from django.utils import six
from django.utils.deprecation import RemovedInDjango19Warning
@@ -329,6 +330,15 @@ class TemplateViewTest(TestCase):
response = self.client.get('/template/content_type/')
self.assertEqual(response['Content-Type'], 'text/plain')
+ def test_resolve_view(self):
+ match = resolve('/template/content_type/')
+ self.assertIs(match.func.view_class, TemplateView)
+ self.assertEqual(match.func.view_initkwargs['content_type'], 'text/plain')
+
+ def test_resolve_login_required_view(self):
+ match = resolve('/template/login_required/')
+ self.assertIs(match.func.view_class, TemplateView)
+
@ignore_warnings(category=RemovedInDjango19Warning)
@override_settings(ROOT_URLCONF='generic_views.urls')
diff --git a/tests/generic_views/urls.py b/tests/generic_views/urls.py
index 1bef0a8b77..e09ee12562 100644
--- a/tests/generic_views/urls.py
+++ b/tests/generic_views/urls.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.conf.urls import url
from django.contrib.auth import views as auth_views
+from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_page
from django.views.generic import TemplateView
@@ -14,6 +15,8 @@ urlpatterns = [
# TemplateView
url(r'^template/no_template/$',
TemplateView.as_view()),
+ url(r'^template/login_required/$',
+ login_required(TemplateView.as_view())),
url(r'^template/simple/(?P<foo>\w+)/$',
TemplateView.as_view(template_name='generic_views/about.html')),
url(r'^template/custom/(?P<foo>\w+)/$',