From b79df0b35861400f573e74d0305d7298c221e7ff Mon Sep 17 00:00:00 2001 From: Ian Wilson Date: Fri, 6 Sep 2013 16:25:34 -0500 Subject: [PATCH 1/2] adds fix for SingleObjectTemplateResponseMixin raising a TemplateDoesNotExist when it should have raised an ImproperlyConfigured. fixes 16502. by @ianawilson, @jambonrose --- django/views/generic/detail.py | 48 ++++++++++++++++++-------------- tests/generic_views/test_base.py | 12 ++++++++ tests/generic_views/views.py | 8 ++++++ 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py index 5ce8092c670..466954c03a2 100644 --- a/django/views/generic/detail.py +++ b/django/views/generic/detail.py @@ -137,28 +137,34 @@ class SingleObjectTemplateResponseMixin(TemplateResponseMixin): # we just start with an empty list. names = [] - # If self.template_name_field is set, grab the value of the field - # of that name from the object; this is the most specific template - # name, if given. - if self.object and self.template_name_field: - name = getattr(self.object, self.template_name_field, None) - if name: - names.insert(0, name) + # If self.template_name_field is set, grab the value of the field + # of that name from the object; this is the most specific template + # name, if given. + if self.object and self.template_name_field: + name = getattr(self.object, self.template_name_field, None) + if name: + names.insert(0, name) + + # The least-specific option is the default /_detail.html; + # only use this if the object in question is a model. + if isinstance(self.object, models.Model): + names.append("%s/%s%s.html" % ( + self.object._meta.app_label, + self.object._meta.model_name, + self.template_name_suffix + )) + elif hasattr(self, 'model') and self.model is not None and issubclass(self.model, models.Model): + names.append("%s/%s%s.html" % ( + self.model._meta.app_label, + self.model._meta.model_name, + self.template_name_suffix + )) + + # If we still haven't managed to find any template names, we should + # re-raise the ImproperlyConfigured to alert the user. + if not names: + raise - # The least-specific option is the default /_detail.html; - # only use this if the object in question is a model. - if isinstance(self.object, models.Model): - names.append("%s/%s%s.html" % ( - self.object._meta.app_label, - self.object._meta.model_name, - self.template_name_suffix - )) - elif hasattr(self, 'model') and self.model is not None and issubclass(self.model, models.Model): - names.append("%s/%s%s.html" % ( - self.model._meta.app_label, - self.model._meta.model_name, - self.template_name_suffix - )) return names diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py index b1dd7a3040b..bd354ee091e 100644 --- a/tests/generic_views/test_base.py +++ b/tests/generic_views/test_base.py @@ -468,3 +468,15 @@ class UseMultipleObjectMixinTest(unittest.TestCase): # Overwrite the view's queryset with queryset from kwarg context = test_view.get_context_data(object_list=queryset) self.assertEqual(context['object_list'], queryset) + + +class SingleObjectTemplateResponseMixinTest(unittest.TestCase): + + def test_create_view_with_form_only(self): + """ + We want to makes sure that if you use a template mixin, but forget the + template, it still tells you it's ImproperlyConfigured instead of + TemplateDoesNotExist. + """ + view = views.TemplateResponseWithoutTemplate() + self.assertRaises(ImproperlyConfigured, view.get_template_names) diff --git a/tests/generic_views/views.py b/tests/generic_views/views.py index f839b537532..aaff644a14c 100644 --- a/tests/generic_views/views.py +++ b/tests/generic_views/views.py @@ -92,6 +92,14 @@ class NaiveAuthorCreate(generic.CreateView): fields = '__all__' +class TemplateResponseWithoutTemplate(generic.detail.SingleObjectTemplateResponseMixin, generic.View): + # we don't define the usual template_name here + + def __init__(self): + # Dummy object, but attr is required by get_template_name() + self.object = None + + class AuthorCreate(generic.CreateView): model = Author success_url = '/list/authors/' From d0051308450880dbc2df6de96a6d1aab954df000 Mon Sep 17 00:00:00 2001 From: Ian Wilson Date: Fri, 6 Sep 2013 17:20:43 -0500 Subject: [PATCH 2/2] fixed test name from an old, overly specific iteration of the test --- tests/generic_views/test_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/generic_views/test_base.py b/tests/generic_views/test_base.py index bd354ee091e..5dd6815d05e 100644 --- a/tests/generic_views/test_base.py +++ b/tests/generic_views/test_base.py @@ -472,7 +472,7 @@ class UseMultipleObjectMixinTest(unittest.TestCase): class SingleObjectTemplateResponseMixinTest(unittest.TestCase): - def test_create_view_with_form_only(self): + def test_template_mixin_without_template(self): """ We want to makes sure that if you use a template mixin, but forget the template, it still tells you it's ImproperlyConfigured instead of