﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
19261	Page.__getitem__ usage causes queryset to evaluate when doing method lookups	trbs	nobody	"The code for Page.__getitem__ forces an evaluation (query to the database) of the queryset when it's actually looking up the name the name of class functions.

Python: 2.7 (think 2.6 as well)
Django: 1.4.x

The function looks like this:
{{{
    def __getitem__(self, index):
        # The object_list is converted to a list so that if it was a QuerySe    t
        # it won't be a database hit per __getitem__.
        return super(Page, self).__getitem__(self, index)
}}}

Now consider this template code that runs from a generic class based view:

{{{
{% if page_obj.has_previous %}
...
{% endif %}
}}}

Here ```page_obj.has_previous``` generates a call to __getitem__ with 'has_previous' as its parameter ```index```.

This translates to:

{{{
return list(self.object_list)['has_previous']
}}}

Which raises a ```TypeError```: ```list indices must be integers, not unicode````.
And as per http://docs.python.org/2/reference/datamodel.html#object.__getitem__ this is nicely ignored and __getitem__ returns the correct attribute.

However before the type error, during list(self.object_list) the queryset is executed. This should not happen if it's not necessary. It defeats caching in some cases, the query could be expensive and is generally not what we would expect when calling a Page instance's methods.

To avoid this for the (quite common) usage of __getitem__, I suggest something in the lines of:

{{{
﻿   def __getitem__(self, index):
        # The object_list is converted to a list so that if it was a QuerySet
        # it won't be a database hit per __getitem__.
        if isinstance(index, (int,long)):
            return list(self.object_list)[index]
        return super(Page, self).__getitem__(self, index)
}}}

(Maybe we don't need to check for long ? and is there maybe some other type that we should check ?)

Patch does not yet includes tests for this. However I'm not really sure what test would actually check this. As the type error is actually swallowed by Python itself.

(btw: i set easy-pickings, as finding it out was not necessarily 'easy' but fixing it should hopefully be)"	Cleanup/optimization	closed	Template system	1.4	Normal	fixed	page, type_error, __getitem__, pagination		Accepted	1	0	1	0	1	0
