Fixed #24055 -- Keep reference to view class for resolve()
This commit is contained in:
parent
67235fd4ef
commit
a420f83e7d
|
@ -583,6 +583,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
def wrap(view):
|
def wrap(view):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return self.admin_site.admin_view(view)(*args, **kwargs)
|
return self.admin_site.admin_view(view)(*args, **kwargs)
|
||||||
|
wrapper.model_admin = self
|
||||||
return update_wrapper(wrapper, view)
|
return update_wrapper(wrapper, view)
|
||||||
|
|
||||||
info = self.model._meta.app_label, self.model._meta.model_name
|
info = self.model._meta.app_label, self.model._meta.model_name
|
||||||
|
|
|
@ -245,6 +245,7 @@ class AdminSite(object):
|
||||||
def wrap(view, cacheable=False):
|
def wrap(view, cacheable=False):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return self.admin_view(view, cacheable)(*args, **kwargs)
|
return self.admin_view(view, cacheable)(*args, **kwargs)
|
||||||
|
wrapper.admin_site = self
|
||||||
return update_wrapper(wrapper, view)
|
return update_wrapper(wrapper, view)
|
||||||
|
|
||||||
# Admin-site-wide views.
|
# Admin-site-wide views.
|
||||||
|
|
|
@ -69,6 +69,8 @@ class View(object):
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
return self.dispatch(request, *args, **kwargs)
|
return self.dispatch(request, *args, **kwargs)
|
||||||
|
view.view_class = cls
|
||||||
|
view.view_initkwargs = initkwargs
|
||||||
|
|
||||||
# take name and docstring from class
|
# take name and docstring from class
|
||||||
update_wrapper(view, cls, updated=())
|
update_wrapper(view, cls, updated=())
|
||||||
|
|
|
@ -65,6 +65,11 @@ View
|
||||||
|
|
||||||
response = MyView.as_view()(request)
|
response = MyView.as_view()(request)
|
||||||
|
|
||||||
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The returned view has ``view_class`` and ``view_initkwargs``
|
||||||
|
attributes.
|
||||||
|
|
||||||
.. method:: dispatch(request, *args, **kwargs)
|
.. method:: dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
The ``view`` part of the view -- the method that accepts a ``request``
|
The ``view`` part of the view -- the method that accepts a ``request``
|
||||||
|
|
|
@ -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))
|
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)
|
.. method:: ModelAdmin.get_form(request, obj=None, **kwargs)
|
||||||
|
|
||||||
Returns a :class:`~django.forms.ModelForm` class for use in the admin add
|
Returns a :class:`~django.forms.ModelForm` class for use in the admin add
|
||||||
|
|
|
@ -33,7 +33,7 @@ Minor features
|
||||||
:mod:`django.contrib.admin`
|
:mod:`django.contrib.admin`
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
* ...
|
* Admin views now have ``model_admin`` or ``admin_site`` attributes.
|
||||||
|
|
||||||
:mod:`django.contrib.auth`
|
: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
|
Internationalization
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.core.checks import Error
|
||||||
from django.core.files import temp as tempfile
|
from django.core.files import temp as tempfile
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.urlresolvers import (NoReverseMatch,
|
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.
|
# Register auth models with the admin.
|
||||||
from django.contrib.auth import get_permission_codename
|
from django.contrib.auth import get_permission_codename
|
||||||
from django.contrib.admin import ModelAdmin
|
from django.contrib.admin import ModelAdmin
|
||||||
|
@ -56,6 +56,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
|
||||||
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
|
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
|
||||||
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker,
|
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker,
|
||||||
ParentWithDependentChildren, Character, FieldOverridePost, Color2)
|
ParentWithDependentChildren, Character, FieldOverridePost, Color2)
|
||||||
|
from . import customadmin
|
||||||
from .admin import site, site2, CityAdmin
|
from .admin import site, site2, CityAdmin
|
||||||
|
|
||||||
|
|
||||||
|
@ -749,6 +750,12 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
||||||
with self.assertRaises(NoReverseMatch):
|
with self.assertRaises(NoReverseMatch):
|
||||||
reverse('admin:app_list', args=('admin_views2',))
|
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):
|
def test_proxy_model_content_type_is_used_for_log_entries(self):
|
||||||
"""
|
"""
|
||||||
Log entries for proxy models should have the proxy model's content
|
Log entries for proxy models should have the proxy model's content
|
||||||
|
|
|
@ -5,6 +5,7 @@ import unittest
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.core.urlresolvers import resolve
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.deprecation import RemovedInDjango19Warning
|
from django.utils.deprecation import RemovedInDjango19Warning
|
||||||
|
@ -329,6 +330,15 @@ class TemplateViewTest(TestCase):
|
||||||
response = self.client.get('/template/content_type/')
|
response = self.client.get('/template/content_type/')
|
||||||
self.assertEqual(response['Content-Type'], 'text/plain')
|
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)
|
@ignore_warnings(category=RemovedInDjango19Warning)
|
||||||
@override_settings(ROOT_URLCONF='generic_views.urls')
|
@override_settings(ROOT_URLCONF='generic_views.urls')
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from django.contrib.auth import views as auth_views
|
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.decorators.cache import cache_page
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ urlpatterns = [
|
||||||
# TemplateView
|
# TemplateView
|
||||||
url(r'^template/no_template/$',
|
url(r'^template/no_template/$',
|
||||||
TemplateView.as_view()),
|
TemplateView.as_view()),
|
||||||
|
url(r'^template/login_required/$',
|
||||||
|
login_required(TemplateView.as_view())),
|
||||||
url(r'^template/simple/(?P<foo>\w+)/$',
|
url(r'^template/simple/(?P<foo>\w+)/$',
|
||||||
TemplateView.as_view(template_name='generic_views/about.html')),
|
TemplateView.as_view(template_name='generic_views/about.html')),
|
||||||
url(r'^template/custom/(?P<foo>\w+)/$',
|
url(r'^template/custom/(?P<foo>\w+)/$',
|
||||||
|
|
Loading…
Reference in New Issue