From 4d11ea1ef01eba14b3a48a727f07f723f782fd84 Mon Sep 17 00:00:00 2001 From: Clifford Gama Date: Tue, 22 Oct 2024 14:12:02 +0200 Subject: [PATCH] Fixed #28999 -- Documented how to reverse a class-based view by instance. Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> --- docs/ref/urlresolvers.txt | 23 ++++++++++++++++++++++- tests/urlpatterns_reverse/tests.py | 4 ++-- tests/urlpatterns_reverse/urls.py | 2 +- tests/urlpatterns_reverse/views.py | 4 ++-- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/ref/urlresolvers.txt b/docs/ref/urlresolvers.txt index b335d1fc39..3c3be76e75 100644 --- a/docs/ref/urlresolvers.txt +++ b/docs/ref/urlresolvers.txt @@ -13,7 +13,8 @@ your code, Django provides the following function: .. function:: reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None) ``viewname`` can be a :ref:`URL pattern name ` or the -callable view object. For example, given the following ``url``:: +callable view object used in the URLconf. For example, given the following +``url``:: from news import views @@ -79,6 +80,26 @@ use for reversing. By default, the root URLconf for the current thread is used. Applying further encoding (such as :func:`urllib.parse.quote`) to the output of ``reverse()`` may produce undesirable results. +.. admonition:: Reversing class-based views by view object + + The view object can also be the result of calling + :meth:`~django.views.generic.base.View.as_view` if the same view object is + used in the URLConf. Following the original example, the view object could + be defined as: + + .. code-block:: python + :caption: ``news/views.py`` + + from django.views import View + + + class ArchiveView(View): ... + + + archive = ArchiveView.as_view() + + However, remember that namespaced views cannot be reversed by view object. + ``reverse_lazy()`` ================== diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py index 216545b5f5..91d3f237ec 100644 --- a/tests/urlpatterns_reverse/tests.py +++ b/tests/urlpatterns_reverse/tests.py @@ -522,12 +522,12 @@ class URLPatternReverse(SimpleTestCase): with self.assertRaisesMessage(NoReverseMatch, msg): reverse("places", kwargs={"arg1": 2}) - def test_func_view_from_cbv(self): + def test_view_func_from_cbv(self): expected = "/hello/world/" url = reverse(views.view_func_from_cbv, kwargs={"name": "world"}) self.assertEqual(url, expected) - def test_func_view_from_cbv_no_expected_kwarg(self): + def test_view_func_from_cbv_no_expected_kwarg(self): with self.assertRaises(NoReverseMatch): reverse(views.view_func_from_cbv) diff --git a/tests/urlpatterns_reverse/urls.py b/tests/urlpatterns_reverse/urls.py index 5bf20a3f63..aca2d06ef7 100644 --- a/tests/urlpatterns_reverse/urls.py +++ b/tests/urlpatterns_reverse/urls.py @@ -137,6 +137,6 @@ urlpatterns = [ path("includes/", include(other_patterns)), # Security tests re_path("(.+)/security/$", empty_view, name="security"), - # View function from cbv + # View function from cbv. path("hello//", view_func_from_cbv), ] diff --git a/tests/urlpatterns_reverse/views.py b/tests/urlpatterns_reverse/views.py index aa55917ec0..01dfc1309e 100644 --- a/tests/urlpatterns_reverse/views.py +++ b/tests/urlpatterns_reverse/views.py @@ -58,12 +58,12 @@ def bad_view(request, *args, **kwargs): raise ValueError("I don't think I'm getting good value for this view") -class _HelloView(View): +class HelloView(View): def get(self, request, *args, **kwargs): return HttpResponse(f"Hello {self.kwargs['name']}") -view_func_from_cbv = _HelloView.as_view() +view_func_from_cbv = HelloView.as_view() empty_view_partial = partial(empty_view, template_name="template.html") empty_view_nested_partial = partial(