#29158 closed Bug (fixed)
ModelChoiceField crashes when checking choices' length if queryset is a manager
| Reported by: | François Freitag | Owned by: | François Freitag |
|---|---|---|---|
| Component: | Forms | Version: | 1.8 |
| Severity: | Normal | Keywords: | |
| Cc: | Gavin Wahl | Triage Stage: | Ready for checkin |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
ModelChoiceField must accept Manager as a .queryset for backward compatibility reasons (see #25683). However, ModelChoiceIterator does not play nice with Managers:
class TestModelChoiceField(TestCase):
def test_queryset_manager_has_length(self):
f = ModelChoiceField(ChoiceOptionModel.objects)
len(f.choices)
Errors with:
======================================================================
ERROR: test_queryset_manager_has_length (forms_tests.test_tmp.TestModelChoiceField)
----------------------------------------------------------------------
Traceback (most recent call last):
File "django/tests/forms_tests/test_tmp.py", line 10, in test_queryset_manager_has_length
len(f.choices)
File "django/django/forms/models.py", line 1141, in __len__
return len(self.queryset) + (1 if self.field.empty_label is not None else 0)
TypeError: object of type 'Manager' has no len()
The reason why this TypeError was not reported earlier is probably because Python swallows TypeError silently for __len__ when list is called, because generators have no len:
Python 3.6.4 (default, Jan 5 2018, 02:35:40) [GCC 7.2.1 20171224] on linux Type "help", "copyright", "credits" or "license" for more information. >>> def gene(): ... yield 1 ... >>> len(gene()) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type 'generator' has no len() >>> list(gene()) [1]
Change History (5)
comment:1 by , 8 years ago
| Has patch: | set |
|---|
comment:2 by , 8 years ago
| Summary: | ModelChoiceField crashes when checking choices' length → ModelChoiceField crashes when checking choices' length if queryset is a manager |
|---|---|
| Triage Stage: | Unreviewed → Ready for checkin |
| Type: | Uncategorized → Bug |
(pending a few cosmetic updates)
comment:4 by , 5 years ago
The fix has introduced a problem where the queryset is cloned while setting it. This causes redudant queries when there are copies of the same for, ie a formset.
comment:5 by , 5 years ago
| Cc: | added |
|---|
Hi Gavin — can I ask you to follow-up in a new ticket with a minimal reproduce of the issue you're seeing here please? Thanks!
PR