#28312: ModelChoiceIterator uses cached length of queryset.
------------------------------------+--------------------------------------
Reporter: Sjoerd Job Postmus | Owner: nobody
Type: Bug | Status: new
Component: Forms | Version: 1.8
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
------------------------------------+--------------------------------------
Comment (by Sjoerd Job Postmus):
The following two tests that show how I would expect the
`ModelMultipleChoiceField` to work. The first tests `__iter__` (and
works), the second tests `__len__` (and fails: `AssertionError: 3 != 4`).
{{{
diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py
index c85eb2a..3c6241d 100644
--- a/tests/model_forms/tests.py
+++ b/tests/model_forms/tests.py
@@ -1992,6 +1992,27 @@ class ModelMultipleChoiceFieldTests(TestCase):
form = ArticleCategoriesForm(instance=article)
self.assertCountEqual(form['categories'].value(), [self.c2.slug,
self.c3.slug])
+ def test_added_fields_gets_rendered(self):
+ f = forms.ModelMultipleChoiceField(Category.objects.all())
+ self.assertEqual(list(f.choices), [
+ (self.c1.pk, 'Entertainment'),
+ (self.c2.pk, "It's a test"),
+ (self.c3.pk, 'Third')])
+ c4 = Category.objects.create(
+ name="Now you see me", slug="now", url="added")
+ self.assertEqual(list(f.choices), [
+ (self.c1.pk, 'Entertainment'),
+ (self.c2.pk, "It's a test"),
+ (self.c3.pk, 'Third'),
+ (c4.pk, 'Now you see me')])
+
+ def test_added_fields_gets_counted(self):
+ f = forms.ModelMultipleChoiceField(Category.objects.all())
+ self.assertEqual(len(f.choices), 3)
+ c4 = Category.objects.create(
+ name="Now you see me", slug="now", url="added")
+ self.assertEqual(len(f.choices), 4)
+
class ModelOneToOneFieldTests(TestCase):
def test_modelform_onetoonefield(self):
}}}
This means that the "invariant" that `len(f.choices) ==
len(list(f.choices))` does not hold.
In particular: note that (currently) the value is calculated just once:
the first time `__len__` is called. This caching is not limited to 'per
request', but is cached for the lifetime of the process handling requests.
--
Ticket URL: <https://code.djangoproject.com/ticket/28312#comment:2>
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/067.61efd7585181757bd7e02a215427c251%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.