Commit 5e06fa14 authored by Vincent-Vega's avatar Vincent-Vega Committed by Tim Graham
Browse files

Fixed #22745 -- Prevented reevaluation of ModelChoiceField's queryset when...

Fixed #22745 -- Prevented reevaluation of ModelChoiceField's queryset when accesssing BoundField's attrs.

Thanks Christian Schmitt for review.
parent 399cf303
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -529,6 +529,10 @@ class BoundField(object):
        return len(list(self.__iter__()))

    def __getitem__(self, idx):
        # Prevent unnecessary reevaluation when accessing BoundField's attrs
        # from templates.
        if not isinstance(idx, six.integer_types):
            raise TypeError
        return list(self.__iter__())[idx]

    @property
+31 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from django.db import connection
from django.db.models.query import EmptyQuerySet
from django.forms.models import (construct_instance, fields_for_model,
    model_to_dict, modelform_factory, ModelFormMetaclass)
from django.template import Template, Context
from django.test import TestCase, skipUnlessDBFeature
from django.utils._os import upath
from django.utils import six
@@ -1466,6 +1467,21 @@ class ModelChoiceFieldTests(TestCase):
        self.assertTrue(field1 is not ModelChoiceForm.base_fields['category'])
        self.assertTrue(field1.widget.choices.field is field1)

    def test_modelchoicefield_22745(self):
        """
        #22745 -- Make sure that ModelChoiceField with RadioSelect widget
        doesn't produce unnecessary db queries when accessing its BoundField's
        attrs.
        """
        class ModelChoiceForm(forms.Form):
            category = forms.ModelChoiceField(Category.objects.all(), widget=forms.RadioSelect)

        form = ModelChoiceForm()
        field = form['category']  # BoundField
        template = Template('{{ field.name }}{{ field }}{{ field.help_text }}')
        with self.assertNumQueries(1):
            template.render(Context({'field': field}))


class ModelMultipleChoiceFieldTests(TestCase):
    def setUp(self):
@@ -1604,6 +1620,21 @@ class ModelMultipleChoiceFieldTests(TestCase):
        self.assertTrue(form.is_valid())
        self.assertTrue(form.has_changed())

    def test_model_multiple_choice_field_22745(self):
        """
        #22745 -- Make sure that ModelMultipleChoiceField with
        CheckboxSelectMultiple widget doesn't produce unnecessary db queries
        when accessing its BoundField's attrs.
        """
        class ModelMultipleChoiceForm(forms.Form):
            categories = forms.ModelMultipleChoiceField(Category.objects.all(), widget=forms.CheckboxSelectMultiple)

        form = ModelMultipleChoiceForm()
        field = form['categories']  # BoundField
        template = Template('{{ field.name }}{{ field }}{{ field.help_text }}')
        with self.assertNumQueries(1):
            template.render(Context({'field': field}))


class ModelOneToOneFieldTests(TestCase):
    def test_modelform_onetoonefield(self):