From c2c27867ef1d4ad32369f8cda42a6d72b262cae5 Mon Sep 17 00:00:00 2001 From: Felipe Lee Date: Thu, 10 Oct 2019 00:22:43 -0500 Subject: [PATCH] Refs #20456 -- Moved initialization of HEAD method based on GET to the View.setup() for generic views. This will ease unit testing of views since setup will essentially do everything needed to set the view instance up (other than instantiating it). Credit for idea goes to Vincent Prouillet. --- AUTHORS | 1 + django/views/generic/base.py | 4 ++-- docs/ref/class-based-views/base.txt | 7 ++----- tests/generic_views/test_base.py | 7 +++++++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index 983e656ae0..d6667d6f12 100644 --- a/AUTHORS +++ b/AUTHORS @@ -286,6 +286,7 @@ answer newbie questions, and generally made Django that much better: favo@exoweb.net fdr Federico Capoano + Felipe Lee Filip Noetzel Filip Wasilewski Finn Gruwier Larsen diff --git a/django/views/generic/base.py b/django/views/generic/base.py index 5ed4f18ee1..0d6e31e195 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -60,8 +60,6 @@ class View: def view(request, *args, **kwargs): self = cls(**initkwargs) - if hasattr(self, 'get') and not hasattr(self, 'head'): - self.head = self.get self.setup(request, *args, **kwargs) if not hasattr(self, 'request'): raise AttributeError( @@ -82,6 +80,8 @@ class View: def setup(self, request, *args, **kwargs): """Initialize attributes shared by all view methods.""" + if hasattr(self, 'get') and not hasattr(self, 'head'): + self.head = self.get self.request = request self.args = args self.kwargs = kwargs diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt index 9645aa7a91..4c1d0e12b5 100644 --- a/docs/ref/class-based-views/base.txt +++ b/docs/ref/class-based-views/base.txt @@ -79,12 +79,9 @@ MRO is an acronym for Method Resolution Order. .. method:: setup(request, *args, **kwargs) - Initializes view instance attributes: ``self.request``, ``self.args``, - and ``self.kwargs`` prior to :meth:`dispatch`. + Performs key view initialization prior to :meth:`dispatch`. - Overriding this method allows mixins to setup instance attributes for - reuse in child classes. When overriding this method, you must call - ``super()``. + If overriding this method, you must call ``super()``. .. method:: dispatch(request, *args, **kwargs) diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py index f6479d858c..c1ad30526e 100644 --- a/tests/generic_views/test_base.py +++ b/tests/generic_views/test_base.py @@ -113,6 +113,13 @@ class ViewTest(SimpleTestCase): response = SimpleView.as_view()(self.rf.head('/')) self.assertEqual(response.status_code, 200) + def test_setup_get_and_head(self): + view_instance = SimpleView() + self.assertFalse(hasattr(view_instance, 'head')) + view_instance.setup(self.rf.get('/')) + self.assertTrue(hasattr(view_instance, 'head')) + self.assertEqual(view_instance.head, view_instance.get) + def test_head_no_get(self): """ Test a view which supplies no GET method responds to HEAD with HTTP 405.