Fixed #29016 -- Fixed incorrect foreign key nullification on related instance deletion.
This commit is contained in:
parent
cea5fe94c6
commit
9a621edf62
|
@ -284,8 +284,8 @@ class Collector:
|
||||||
|
|
||||||
# update fields
|
# update fields
|
||||||
for model, instances_for_fieldvalues in self.field_updates.items():
|
for model, instances_for_fieldvalues in self.field_updates.items():
|
||||||
query = sql.UpdateQuery(model)
|
|
||||||
for (field, value), instances in instances_for_fieldvalues.items():
|
for (field, value), instances in instances_for_fieldvalues.items():
|
||||||
|
query = sql.UpdateQuery(model)
|
||||||
query.update_batch([obj.pk for obj in instances],
|
query.update_batch([obj.pk for obj in instances],
|
||||||
{field.name: value}, self.using)
|
{field.name: value}, self.using)
|
||||||
|
|
||||||
|
|
|
@ -9,4 +9,5 @@ Django 1.11.10 fixes several bugs in 1.11.9.
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed incorrect foreign key nullification if a model has two foreign keys to
|
||||||
|
the same model and a target model is deleted (:ticket:`29016`).
|
||||||
|
|
|
@ -11,3 +11,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed hidden content at the bottom of the "The install worked successfully!"
|
* Fixed hidden content at the bottom of the "The install worked successfully!"
|
||||||
page for some languages (:ticket:`28885`).
|
page for some languages (:ticket:`28885`).
|
||||||
|
|
||||||
|
* Fixed incorrect foreign key nullification if a model has two foreign keys to
|
||||||
|
the same model and a target model is deleted (:ticket:`29016`).
|
||||||
|
|
|
@ -56,6 +56,8 @@ class Email(Contact):
|
||||||
|
|
||||||
class Researcher(models.Model):
|
class Researcher(models.Model):
|
||||||
contacts = models.ManyToManyField(Contact, related_name="research_contacts")
|
contacts = models.ManyToManyField(Contact, related_name="research_contacts")
|
||||||
|
primary_contact = models.ForeignKey(Contact, models.SET_NULL, null=True, related_name='primary_contacts')
|
||||||
|
secondary_contact = models.ForeignKey(Contact, models.SET_NULL, null=True, related_name='secondary_contacts')
|
||||||
|
|
||||||
|
|
||||||
class Food(models.Model):
|
class Food(models.Model):
|
||||||
|
|
|
@ -4,7 +4,7 @@ from django.db import connection, models, transaction
|
||||||
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
|
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Award, AwardNote, Book, Child, Eaten, Email, File, Food, FooFile,
|
Award, AwardNote, Book, Child, Contact, Eaten, Email, File, Food, FooFile,
|
||||||
FooFileProxy, FooImage, FooPhoto, House, Image, Item, Location, Login,
|
FooFileProxy, FooImage, FooPhoto, House, Image, Item, Location, Login,
|
||||||
OrderedPerson, OrgUnit, Person, Photo, PlayedWith, PlayedWithNote, Policy,
|
OrderedPerson, OrgUnit, Person, Photo, PlayedWith, PlayedWithNote, Policy,
|
||||||
Researcher, Toy, Version,
|
Researcher, Toy, Version,
|
||||||
|
@ -334,7 +334,7 @@ class Ticket19102Tests(TestCase):
|
||||||
self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
|
self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
|
||||||
|
|
||||||
|
|
||||||
class OrderedDeleteTests(TestCase):
|
class DeleteTests(TestCase):
|
||||||
def test_meta_ordered_delete(self):
|
def test_meta_ordered_delete(self):
|
||||||
# When a subquery is performed by deletion code, the subquery must be
|
# When a subquery is performed by deletion code, the subquery must be
|
||||||
# cleared of all ordering. There was a but that caused _meta ordering
|
# cleared of all ordering. There was a but that caused _meta ordering
|
||||||
|
@ -344,3 +344,27 @@ class OrderedDeleteTests(TestCase):
|
||||||
OrderedPerson.objects.create(name='Bob', lives_in=h)
|
OrderedPerson.objects.create(name='Bob', lives_in=h)
|
||||||
OrderedPerson.objects.filter(lives_in__address='Foo').delete()
|
OrderedPerson.objects.filter(lives_in__address='Foo').delete()
|
||||||
self.assertEqual(OrderedPerson.objects.count(), 0)
|
self.assertEqual(OrderedPerson.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_foreign_key_delete_nullifies_correct_columns(self):
|
||||||
|
"""
|
||||||
|
With a model (Researcher) that has two foreign keys pointing to the
|
||||||
|
same model (Contact), deleting an instance of the target model
|
||||||
|
(contact1) nullifies the correct fields of Researcher.
|
||||||
|
"""
|
||||||
|
contact1 = Contact.objects.create(label='Contact 1')
|
||||||
|
contact2 = Contact.objects.create(label='Contact 2')
|
||||||
|
researcher1 = Researcher.objects.create(
|
||||||
|
primary_contact=contact1,
|
||||||
|
secondary_contact=contact2,
|
||||||
|
)
|
||||||
|
researcher2 = Researcher.objects.create(
|
||||||
|
primary_contact=contact2,
|
||||||
|
secondary_contact=contact1,
|
||||||
|
)
|
||||||
|
contact1.delete()
|
||||||
|
researcher1.refresh_from_db()
|
||||||
|
researcher2.refresh_from_db()
|
||||||
|
self.assertIsNone(researcher1.primary_contact)
|
||||||
|
self.assertEqual(researcher1.secondary_contact, contact2)
|
||||||
|
self.assertEqual(researcher2.primary_contact, contact2)
|
||||||
|
self.assertIsNone(researcher2.secondary_contact)
|
||||||
|
|
Loading…
Reference in New Issue