lazy: only create resultset on numeric access to __getitem__ (#33262)

This commit is contained in:
Frédéric Péters 2019-05-20 13:26:38 +02:00
parent 96fcc9b585
commit 2eb1614dbb
2 changed files with 16 additions and 0 deletions

View File

@ -795,6 +795,13 @@ def test_lazy_formdata_queryset(pub, variable_test_data):
qs = lazy_formdata.objects.pending().order_by('id')
assert [x.number for x in qs] == ['1-1', '1-2', '1-3', '1-4', '1-5', '1-6', '1-7']
# Check accessing an non-numeric attribute doesn't try to cache things
# (see code for explanation)
manager = lazy_formdata.objects
with pytest.raises(TypeError):
manager['drafts']
assert manager._cached_resultset is None
def test_lazy_formdata_queryset_distance(pub, variable_test_data):
lazy_formdata = variable_test_data
formdef = lazy_formdata._formdef

View File

@ -110,6 +110,15 @@ class LazyFormDefObjectsManager(object):
return self.count
def __getitem__(self, key):
try:
int(key)
except ValueError:
# A django template doing formdef.objects.drafts would start by
# doing ['drafts'], that would raise TypeError and then continue
# to accessing .drafts (this is done in _resolve_lookup).
# We need to abort earlier as we don't want to load all formdata
# in that situation.
raise TypeError
if self._cached_resultset is None:
self._cached_resultset = [LazyFormData(x) for x in
self._formdef.data_class().select(clause=self._criterias, order_by=self._order_by)]