Fixed #31095 -- Made RelatedManager.set() preserve existing m2m relations with an invalid type.

This commit is contained in:
Hasan Ramezani 2019-12-19 11:08:02 +01:00 committed by Mariusz Felisiak
parent 5a4d7285bd
commit a3fc24f014
2 changed files with 15 additions and 1 deletions

View File

@ -999,7 +999,8 @@ def create_forward_many_to_many_manager(superclass, rel, reverse):
for obj in objs: for obj in objs:
fk_val = ( fk_val = (
self.target_field.get_foreign_related_value(obj)[0] self.target_field.get_foreign_related_value(obj)[0]
if isinstance(obj, self.model) else obj if isinstance(obj, self.model)
else self.target_field.get_prep_value(obj)
) )
if fk_val in old_ids: if fk_val in old_ids:
old_ids.remove(fk_val) old_ids.remove(fk_val)

View File

@ -469,6 +469,19 @@ class ManyToManyTests(TestCase):
self.a4.publications.set([], clear=True) self.a4.publications.set([], clear=True)
self.assertQuerysetEqual(self.a4.publications.all(), []) self.assertQuerysetEqual(self.a4.publications.all(), [])
def test_set_existing_different_type(self):
# Existing many-to-many relations remain the same for values provided
# with a different type.
ids = set(Publication.article_set.through.objects.filter(
article__in=[self.a4, self.a3],
publication=self.p2,
).values_list('id', flat=True))
self.p2.article_set.set([str(self.a4.pk), str(self.a3.pk)])
new_ids = set(Publication.article_set.through.objects.filter(
publication=self.p2,
).values_list('id', flat=True))
self.assertEqual(ids, new_ids)
def test_assign_forward(self): def test_assign_forward(self):
msg = ( msg = (
"Direct assignment to the reverse side of a many-to-many set is " "Direct assignment to the reverse side of a many-to-many set is "