[2.0.x] Fixed #29296 -- Fixed crashes in admindocs when a view is a callable object.
Backport of 33a0b7ac81
from master
This commit is contained in:
parent
d5018abf1c
commit
1ed31efb87
1
AUTHORS
1
AUTHORS
|
@ -629,6 +629,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Paul Bissex <http://e-scribe.com/>
|
||||
Paul Collier <paul@paul-collier.com>
|
||||
Paul Collins <paul.collins.iii@gmail.com>
|
||||
Paul Donohue <django@PaulSD.com>
|
||||
Paul Lanier <planier@google.com>
|
||||
Paul McLanahan <paul@mclanahan.net>
|
||||
Paul McMillan <Paul@McMillan.ws>
|
||||
|
|
|
@ -2,6 +2,8 @@ from django.conf import settings
|
|||
from django.http import HttpResponse
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
|
||||
from .utils import get_view_name
|
||||
|
||||
|
||||
class XViewMiddleware(MiddlewareMixin):
|
||||
"""
|
||||
|
@ -24,5 +26,5 @@ class XViewMiddleware(MiddlewareMixin):
|
|||
if request.method == 'HEAD' and (request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS or
|
||||
(request.user.is_active and request.user.is_staff)):
|
||||
response = HttpResponse()
|
||||
response['X-View'] = "%s.%s" % (view_func.__module__, view_func.__name__)
|
||||
response['X-View'] = get_view_name(view_func)
|
||||
return response
|
||||
|
|
|
@ -18,6 +18,12 @@ else:
|
|||
docutils_is_available = True
|
||||
|
||||
|
||||
def get_view_name(view_func):
|
||||
mod_name = view_func.__module__
|
||||
view_name = getattr(view_func, '__qualname__', view_func.__class__.__name__)
|
||||
return mod_name + '.' + view_name
|
||||
|
||||
|
||||
def trim_docstring(docstring):
|
||||
"""
|
||||
Uniformly trim leading/trailing whitespace from docstrings.
|
||||
|
|
|
@ -23,6 +23,8 @@ from django.utils.inspect import (
|
|||
from django.utils.translation import gettext as _
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from .utils import get_view_name
|
||||
|
||||
# Exclude methods starting with these strings from documentation
|
||||
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')
|
||||
|
||||
|
@ -128,18 +130,13 @@ class TemplateFilterIndexView(BaseAdminDocsView):
|
|||
class ViewIndexView(BaseAdminDocsView):
|
||||
template_name = 'admin_doc/view_index.html'
|
||||
|
||||
@staticmethod
|
||||
def _get_full_name(func):
|
||||
mod_name = func.__module__
|
||||
return '%s.%s' % (mod_name, func.__qualname__)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
views = []
|
||||
urlconf = import_module(settings.ROOT_URLCONF)
|
||||
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
|
||||
for (func, regex, namespace, name) in view_functions:
|
||||
views.append({
|
||||
'full_name': self._get_full_name(func),
|
||||
'full_name': get_view_name(func),
|
||||
'url': simplify_regex(regex),
|
||||
'url_name': ':'.join((namespace or []) + (name and [name] or [])),
|
||||
'namespace': ':'.join((namespace or [])),
|
||||
|
|
|
@ -12,3 +12,6 @@ Bugfixes
|
|||
* Fixed a regression in Django 1.11.8 where altering a field with a unique
|
||||
constraint may drop and rebuild more foreign keys than necessary
|
||||
(:ticket:`29193`).
|
||||
|
||||
* Fixed crashes in ``django.contrib.admindocs`` when a view is a callable
|
||||
object, such as ``django.contrib.syndication.views.Feed`` (:ticket:`29296`).
|
||||
|
|
|
@ -15,3 +15,6 @@ Bugfixes
|
|||
* Fixed a regression in Django 1.11.8 where altering a field with a unique
|
||||
constraint may drop and rebuild more foreign keys than necessary
|
||||
(:ticket:`29193`).
|
||||
|
||||
* Fixed crashes in ``django.contrib.admindocs`` when a view is a callable
|
||||
object, such as ``django.contrib.syndication.views.Feed`` (:ticket:`29296`).
|
||||
|
|
|
@ -40,3 +40,8 @@ class XViewMiddlewareTest(TestDataMixin, AdminDocsTestCase):
|
|||
user.save()
|
||||
response = self.client.head('/xview/class/')
|
||||
self.assertNotIn('X-View', response)
|
||||
|
||||
def test_callable_object_view(self):
|
||||
self.client.force_login(self.superuser)
|
||||
response = self.client.head('/xview/callable_object/')
|
||||
self.assertEqual(response['X-View'], 'admin_docs.views.XViewCallableObject')
|
||||
|
|
|
@ -51,6 +51,12 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
|||
)
|
||||
self.assertContains(response, 'Views by namespace test')
|
||||
self.assertContains(response, 'Name: <code>test:func</code>.')
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h3><a href="/admindocs/views/admin_docs.views.XViewCallableObject/">'
|
||||
'/xview/callable_object_without_xview/</a></h3>',
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_view_index_with_method(self):
|
||||
"""
|
||||
|
|
|
@ -13,4 +13,6 @@ urlpatterns = [
|
|||
url(r'^', include(ns_patterns, namespace='test')),
|
||||
url(r'^xview/func/$', views.xview_dec(views.xview)),
|
||||
url(r'^xview/class/$', views.xview_dec(views.XViewClass.as_view())),
|
||||
url(r'^xview/callable_object/$', views.xview_dec(views.XViewCallableObject())),
|
||||
url(r'^xview/callable_object_without_xview/$', views.XViewCallableObject()),
|
||||
]
|
||||
|
|
|
@ -13,3 +13,8 @@ def xview(request):
|
|||
class XViewClass(View):
|
||||
def get(self, request):
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
class XViewCallableObject(View):
|
||||
def __call__(self, request):
|
||||
return HttpResponse()
|
||||
|
|
Loading…
Reference in New Issue