Skip to content

Commit

Permalink
Fixed #18949 -- Improve performance of model_to_dict with many-to-many
Browse files Browse the repository at this point in the history
When calling model_to_dict, improve performance of the generated SQL by
using values_list to determine primary keys of many to many objects. Add
a specific test for this function, test_model_to_dict_many_to_many

Thanks to brian for the original report and suggested fix.
  • Loading branch information
aisipos committed Nov 4, 2012
1 parent 8d3f932 commit e44ab5b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion django/forms/models.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def model_to_dict(instance, fields=None, exclude=None):
data[f.name] = [] data[f.name] = []
else: else:
# MultipleChoiceWidget needs a list of pks, not object instances. # MultipleChoiceWidget needs a list of pks, not object instances.
data[f.name] = [obj.pk for obj in f.value_from_object(instance)] data[f.name] = list(f.value_from_object(instance).values_list('pk', flat=True))
else: else:
data[f.name] = f.value_from_object(instance) data[f.name] = f.value_from_object(instance)
return data return data
Expand Down
36 changes: 36 additions & 0 deletions tests/modeltests/model_forms/tests.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -561,6 +561,42 @@ def test_unique_for_date_with_nullable_date(self):
"slug": "Django 1.0"}, instance=p) "slug": "Django 1.0"}, instance=p)
self.assertTrue(form.is_valid()) self.assertTrue(form.is_valid())


class ModelToDictTests(TestCase):
"""
Tests for forms.models.model_to_dict
"""
def test_model_to_dict_many_to_many(self):
categories=[
Category(name='TestName1', slug='TestName1', url='url1'),
Category(name='TestName2', slug='TestName2', url='url2'),
Category(name='TestName3', slug='TestName3', url='url3')
]
for c in categories:
c.save()
writer = Writer(name='Test writer')
writer.save()

art = Article(
headline='Test article',
slug='test-article',
pub_date=datetime.date(1988, 1, 4),
writer=writer,
article='Hello.'
)
art.save()
for c in categories:
art.categories.add(c)
art.save()

with self.assertNumQueries(1):
d = model_to_dict(art)

#Ensure all many-to-many categories appear in model_to_dict
for c in categories:
self.assertIn(c.pk, d['categories'])
#Ensure many-to-many relation appears as a list
self.assertIsInstance(d['categories'], list)

class OldFormForXTests(TestCase): class OldFormForXTests(TestCase):
def test_base_form(self): def test_base_form(self):
self.assertEqual(Category.objects.count(), 0) self.assertEqual(Category.objects.count(), 0)
Expand Down

0 comments on commit e44ab5b

Please sign in to comment.