Merge pull request #769 from oinopion/ticket19816

Fixed #19816 -- pre-evaluate queryset on m2m set
This commit is contained in:
Honza Král 2013-02-23 06:55:09 -08:00
commit 6cb6e1128f
2 changed files with 17 additions and 1 deletions

View File

@ -904,6 +904,9 @@ class ReverseManyRelatedObjectsDescriptor(object):
raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name)) raise AttributeError("Cannot set values on a ManyToManyField which specifies an intermediary model. Use %s.%s's Manager instead." % (opts.app_label, opts.object_name))
manager = self.__get__(instance) manager = self.__get__(instance)
# clear() can change expected output of 'value' queryset, we force evaluation
# of queryset before clear; ticket #19816
value = tuple(value)
manager.clear() manager.clear()
manager.add(*value) manager.add(*value)

View File

@ -5,7 +5,7 @@ from django.test import TestCase
from django.utils import six from django.utils import six
from .models import (SelfRefer, Tag, TagCollection, Entry, SelfReferChild, from .models import (SelfRefer, Tag, TagCollection, Entry, SelfReferChild,
SelfReferChildSibling, Worksheet, RegressionModelSplit) SelfReferChildSibling, Worksheet, RegressionModelSplit, Line)
class M2MRegressionTests(TestCase): class M2MRegressionTests(TestCase):
@ -96,3 +96,16 @@ class M2MRegressionTests(TestCase):
# causes a TypeError in add_lazy_relation # causes a TypeError in add_lazy_relation
m1 = RegressionModelSplit(name='1') m1 = RegressionModelSplit(name='1')
m1.save() m1.save()
def test_m2m_filter(self):
worksheet = Worksheet.objects.create(id=1)
line_hi = Line.objects.create(name="hi")
line_bye = Line.objects.create(name="bye")
worksheet.lines = [line_hi, line_bye]
hi = worksheet.lines.filter(name="hi")
worksheet.lines = hi
self.assertEquals(1, worksheet.lines.count())
self.assertEquals(1, hi.count())