#29893: Unexpected behavior of DetailView on a model defining __len__()
returning
False
-----------------------------------------+------------------------
Reporter: burrscurr | Owner: nobody
Type: Bug | Status: new
Component: Generic views | Version: 2.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 1
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
== Description
When using Django's DetailView on a model defining a {{{__len__()}}}
method, the model object is not always added to context. This is the case,
when {{{__len__()}}} of the model object returns zero. The behavior is
caused by {{{BaseDetailView.get()}}} calling
{{{SingleObjectMixin.get_context_data()}}} which checks like this, if
{{{self.object}}} was set before by{{{SingleObjectMixin.get_object()}}}:
{{{
if self.object:
# adds self.object to context
}}}
Because this check is happening implicitly and not against {{{None}}},
pythons default implementation calling {{{self.object.__len__()}}}
([https://docs.python.org/3/library/stdtypes.html#truth-value-testing])
causes this condition to evaluate to False, at least if {{{__len__()}}}
returns zero. This leads to not having the wanted object in context data.
== Steps to reproduce:
Create an empty model defining a {{{__len__}}} method returning zero and a
DetailView like this:
{{{
class TestModel(models.Model):
def __len__(self):
return 0
class TestModelDetailView(DetailView):
model = TestModel
template_name = 'test.html' # some template
}}}
After creating a TestModel object, the described behavior can be
reproduced when calling the Detailview (url pattern like this
{{{/test/<int:pk>/}}}).
== Proposed solution
Simply checking if self.object is the default value None prevents this not
easy to find bug.
{{{SingleObjectMixin.get_queryset()}}} also has a similar check
{{{
if self.model:
# some action
}}}
which does not seem to cause problems, because {{{self.model}}} is a class
and no object. It should be considered to also check against the default
value for self.model here, which is None.
--
Ticket URL: <https://code.djangoproject.com/ticket/29893>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.ca2801270d3f27b30fa1ecdec36888fa%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.