#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.

Reply via email to