Fixed #19816: pre-evaluate queryset on m2m set
In ReverseManyRelatedObjectsDescriptor.__set__, evaluate possible queryset to avoid problems when clear() would touch data this queryset returns.
This commit is contained in:
parent
1b7fb29dfb
commit
3dddbc0f23
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue