Fixed #25496 -- Made ModelChoiceField respect prefetch_related().
This commit is contained in:
parent
9f2881deb1
commit
6afa6818fc
|
@ -1102,7 +1102,9 @@ class ModelChoiceIterator(object):
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
if self.field.empty_label is not None:
|
if self.field.empty_label is not None:
|
||||||
yield ("", self.field.empty_label)
|
yield ("", self.field.empty_label)
|
||||||
for obj in self.queryset.iterator():
|
# Can't use iterator() when queryset uses prefetch_related()
|
||||||
|
method = 'all' if self.queryset._prefetch_related_lookups else 'iterator'
|
||||||
|
for obj in getattr(self.queryset, method)():
|
||||||
yield self.choice(obj)
|
yield self.choice(obj)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
|
|
@ -9,4 +9,5 @@ Django 1.8.6 fixes several bugs in 1.8.5.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a regression causing ``ModelChoiceField`` to ignore
|
||||||
|
``prefetch_related()`` on its queryset (:ticket:`25496`).
|
||||||
|
|
|
@ -2285,6 +2285,29 @@ class OtherModelFormTests(TestCase):
|
||||||
with self.assertRaises(ValidationError):
|
with self.assertRaises(ValidationError):
|
||||||
f.fields['status'].clean('z')
|
f.fields['status'].clean('z')
|
||||||
|
|
||||||
|
def test_prefetch_related_queryset(self):
|
||||||
|
"""
|
||||||
|
ModelChoiceField should respect a prefetch_related() on its queryset.
|
||||||
|
"""
|
||||||
|
blue = Colour.objects.create(name='blue')
|
||||||
|
red = Colour.objects.create(name='red')
|
||||||
|
multicolor_item = ColourfulItem.objects.create()
|
||||||
|
multicolor_item.colours.add(blue, red)
|
||||||
|
red_item = ColourfulItem.objects.create()
|
||||||
|
red_item.colours.add(red)
|
||||||
|
|
||||||
|
class ColorModelChoiceField(forms.ModelChoiceField):
|
||||||
|
def label_from_instance(self, obj):
|
||||||
|
return ', '.join(c.name for c in obj.colours.all())
|
||||||
|
|
||||||
|
field = ColorModelChoiceField(ColourfulItem.objects.prefetch_related('colours'))
|
||||||
|
with self.assertNumQueries(4): # would be 5 if prefetch is ignored
|
||||||
|
self.assertEqual(tuple(field.choices), (
|
||||||
|
('', '---------'),
|
||||||
|
(multicolor_item.pk, 'blue, red'),
|
||||||
|
(red_item.pk, 'red'),
|
||||||
|
))
|
||||||
|
|
||||||
def test_foreignkeys_which_use_to_field(self):
|
def test_foreignkeys_which_use_to_field(self):
|
||||||
apple = Inventory.objects.create(barcode=86, name='Apple')
|
apple = Inventory.objects.create(barcode=86, name='Apple')
|
||||||
Inventory.objects.create(barcode=22, name='Pear')
|
Inventory.objects.create(barcode=22, name='Pear')
|
||||||
|
|
Loading…
Reference in New Issue