Description

I discovered by writing unit tests for a subclass of DetailView that the get_template_names() method of SingleObjectTemplateResponseMixin (django.views.generic.detail) does not use getattr to access the object attribute.

In the context of writing tests for a subclass overriding (and/or extending) the behavior of get_template_names, "object" may not be present.

The following patch solves the problem permanently:

--- a/django/views/generic/detail.py
+++ b/django/views/generic/detail.py
@@ -119,14 +119,15 @@ class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
# 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:
+ if (getattr(self, 'object', None) and
+ getattr(self, 'template_name_field', None)):
name = getattr(self.object, self.template_name_field, None)
if name:
names.insert(0, name)
# The least-specific option is the default <app>/<model>_detail.html;
# only use this if the object in question is a model.
- if hasattr(self.object, '_meta'):
+ if hasattr(self, 'object') and hasattr(self.object, '_meta'):
names.append("%s/%s%s.html" % (
self.object._meta.app_label,
self.object._meta.object_name.lower(),

A mixin class that performs template-based response rendering for views that operate upon a single object instance. Requires that the view it is mixed with provides self.object, the object instance that the view is operating on. self.object will usually be, but is not required to be, an instance of a Django model. It may be None if the view is in the process of constructing a new instance.

You didn't provide any details on how/what you're overriding/subclassing the UpdateView that includes this mixin, so it's hard to judge if it's a user error or a limitation of the API. Please reopen with more details about your use case.