Skip to content

Commit

Permalink
Ensure consistent output in show_urls for django 4.0+ (#1759)
Browse files Browse the repository at this point in the history
Updates `show_urls` to properly show the view class for class-based
views in django 4.0 and later. There was a regression in django 4.0
that was fixed in django/django@f4b06a3
that resulted in `view` being output in `show_urls` instead of the
actual class name.
  • Loading branch information
jeremy-engel authored Sep 9, 2022
1 parent 9f55f81 commit b0a6a79
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 49 deletions.
2 changes: 2 additions & 0 deletions django_extensions/management/commands/show_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ def handle(self, *args, **options):
func = func.func
decorators.insert(0, 'functools.partial')

if hasattr(func, 'view_class'):
func = func.view_class
if hasattr(func, '__name__'):
func_name = func.__name__
elif hasattr(func, '__class__'):
Expand Down
62 changes: 13 additions & 49 deletions tests/management/commands/test_show_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from django.test import TestCase
from django.test.utils import override_settings
from django.views.generic.base import View
from django import VERSION

from unittest.mock import Mock, patch

Expand Down Expand Up @@ -58,69 +57,44 @@ def test_should_show_urls_unsorted_but_same_order_as_found_in_url_patterns(self,
lines = m_stdout.getvalue().splitlines()
self.assertIn('/lambda/view\ttests.management.commands.test_show_urls.<lambda>', lines[0])
self.assertIn('/function/based/\ttests.management.commands.test_show_urls.function_based_view\tfunction-based-view', lines[1])

if VERSION >= (4, 0):
self.assertIn('/class/based/\ttests.management.commands.test_show_urls.view\tclass-based-view', lines[2])
else:
self.assertIn('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[2])
self.assertIn('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[2])

@patch('sys.stdout', new_callable=StringIO)
def test_should_show_urls_sorted_alphabetically(self, m_stdout):
call_command('show_urls', verbosity=3)

lines = m_stdout.getvalue().splitlines()

if VERSION >= (4, 0):
self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.view\tclass-based-view', lines[0])
else:
self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[0])

self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[0])
self.assertEqual('/function/based/\ttests.management.commands.test_show_urls.function_based_view\tfunction-based-view', lines[1])
self.assertEqual('/lambda/view\ttests.management.commands.test_show_urls.<lambda>', lines[2])

@patch('sys.stdout', new_callable=StringIO)
def test_should_show_urls_in_json_format(self, m_stdout):
call_command('show_urls', '--format=json')

json = [
self.assertJSONEqual(m_stdout.getvalue(), [
{"url": "/lambda/view", "module": "tests.management.commands.test_show_urls.<lambda>", "name": "", "decorators": ""},
{"url": "/function/based/", "module": "tests.management.commands.test_show_urls.function_based_view", "name": "function-based-view", "decorators": ""}
]

if VERSION >= (4, 0):
json.append({"url": "/class/based/", "module": "tests.management.commands.test_show_urls.view", "name": "class-based-view", "decorators": ""})
else:
json.append({"url": "/class/based/", "module": "tests.management.commands.test_show_urls.ClassView", "name": "class-based-view", "decorators": ""})

self.assertJSONEqual(m_stdout.getvalue(), json)
{"url": "/function/based/", "module": "tests.management.commands.test_show_urls.function_based_view", "name": "function-based-view", "decorators": ""},
{"url": "/class/based/", "module": "tests.management.commands.test_show_urls.ClassView", "name": "class-based-view", "decorators": ""}
])
self.assertEqual(len(m_stdout.getvalue().splitlines()), 1)

@patch('sys.stdout', new_callable=StringIO)
def test_should_show_urls_in_pretty_json_format(self, m_stdout):
call_command('show_urls', '--format=pretty-json')

json = [
self.assertJSONEqual(m_stdout.getvalue(), [
{"url": "/lambda/view", "module": "tests.management.commands.test_show_urls.<lambda>", "name": "", "decorators": ""},
{"url": "/function/based/", "module": "tests.management.commands.test_show_urls.function_based_view", "name": "function-based-view", "decorators": ""}
]

if VERSION >= (4, 0):
json.append({"url": "/class/based/", "module": "tests.management.commands.test_show_urls.view", "name": "class-based-view", "decorators": ""})
else:
json.append({"url": "/class/based/", "module": "tests.management.commands.test_show_urls.ClassView", "name": "class-based-view", "decorators": ""})

self.assertJSONEqual(m_stdout.getvalue(), json)
{"url": "/function/based/", "module": "tests.management.commands.test_show_urls.function_based_view", "name": "function-based-view", "decorators": ""},
{"url": "/class/based/", "module": "tests.management.commands.test_show_urls.ClassView", "name": "class-based-view", "decorators": ""}
])
self.assertEqual(len(m_stdout.getvalue().splitlines()), 20)

@patch('sys.stdout', new_callable=StringIO)
def test_should_show_urls_in_table_format(self, m_stdout):
call_command('show_urls', '--format=table')

if VERSION >= (4, 0):
self.assertIn('/class/based/ | tests.management.commands.test_show_urls.view | class-based-view |', m_stdout.getvalue())
else:
self.assertIn('/class/based/ | tests.management.commands.test_show_urls.ClassView | class-based-view |', m_stdout.getvalue())

self.assertIn('/class/based/ | tests.management.commands.test_show_urls.ClassView | class-based-view |', m_stdout.getvalue())
self.assertIn('/function/based/ | tests.management.commands.test_show_urls.function_based_view | function-based-view |', m_stdout.getvalue())
self.assertIn('/lambda/view | tests.management.commands.test_show_urls.<lambda> | |', m_stdout.getvalue())

Expand All @@ -129,12 +103,7 @@ def test_should_show_urls_in_aligned_format(self, m_stdout):
call_command('show_urls', '--format=aligned')

lines = m_stdout.getvalue().splitlines()

if VERSION >= (4, 0):
self.assertEqual('/class/based/ tests.management.commands.test_show_urls.view class-based-view ', lines[0])
else:
self.assertEqual('/class/based/ tests.management.commands.test_show_urls.ClassView class-based-view ', lines[0])

self.assertEqual('/class/based/ tests.management.commands.test_show_urls.ClassView class-based-view ', lines[0])
self.assertEqual('/function/based/ tests.management.commands.test_show_urls.function_based_view function-based-view ', lines[1])
self.assertEqual('/lambda/view tests.management.commands.test_show_urls.<lambda> ', lines[2])

Expand All @@ -143,11 +112,6 @@ def test_should_show_urls_with_no_color_option(self, m_stdout):
call_command('show_urls', '--no-color')

lines = m_stdout.getvalue().splitlines()

if VERSION >= (4, 0):
self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.view\tclass-based-view', lines[0])
else:
self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[0])

self.assertEqual('/class/based/\ttests.management.commands.test_show_urls.ClassView\tclass-based-view', lines[0])
self.assertEqual('/function/based/\ttests.management.commands.test_show_urls.function_based_view\tfunction-based-view', lines[1])
self.assertEqual('/lambda/view\ttests.management.commands.test_show_urls.<lambda>', lines[2])

0 comments on commit b0a6a79

Please sign in to comment.