diff --git a/django/utils/functional.py b/django/utils/functional.py index ddfd882e513..d0be511eaf3 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -298,11 +298,11 @@ class LazyObject(object): __ne__ = new_method_proxy(operator.ne) __hash__ = new_method_proxy(hash) - # Dictionary methods support + # List/Tuple/Dictionary methods support __getitem__ = new_method_proxy(operator.getitem) __setitem__ = new_method_proxy(operator.setitem) __delitem__ = new_method_proxy(operator.delitem) - + __iter__ = new_method_proxy(iter) __len__ = new_method_proxy(len) __contains__ = new_method_proxy(operator.contains) diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index a80f0a2c952..ce2b66f3cb0 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -165,11 +165,22 @@ class LazyObjectTestCase(TestCase): del obj_dict['f'] def test_iter(self): - # LazyObjects don't actually implements __iter__ but you can still - # iterate over them because they implement __getitem__ - obj = self.lazy_wrap([1, 2, 3]) - for expected, actual in zip([1, 2, 3], obj): - self.assertEqual(expected, actual) + # Tests whether an object's custom `__iter__` method is being + # used when iterating over it. + + class IterObject(object): + + def __init__(self, values): + self.values = values + + def __iter__(self): + return iter(self.values) + + original_list = ['test', '123'] + self.assertEqual( + list(self.lazy_wrap(IterObject(original_list))), + original_list + ) def test_pickle(self): # See ticket #16563