summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Plant <L.Plant.98@cantab.net>2011-05-30 16:04:25 +0000
committerLuke Plant <L.Plant.98@cantab.net>2011-05-30 16:04:25 +0000
commitde3b58d6267a01edefb36c22f80c3399c819d465 (patch)
treefd46370039c837d8c2199133843233431a5545f0
parent8ad3c41c69be9b58caef85ef6dde7e07ee299beb (diff)
Fixed #15776 - delete regression in Django 1.3 involving nullable foreign keys
Many thanks to aaron.l.madison for the detailed report and to emulbreh for the fix. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16295 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/db/models/deletion.py6
-rw-r--r--tests/regressiontests/delete_regress/models.py16
-rw-r--r--tests/regressiontests/delete_regress/tests.py10
3 files changed, 28 insertions, 4 deletions
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py
index a52fa24a01..310e3af948 100644
--- a/django/db/models/deletion.py
+++ b/django/db/models/deletion.py
@@ -82,8 +82,8 @@ class Collector(object):
def add(self, objs, source=None, nullable=False, reverse_dependency=False):
"""
Adds 'objs' to the collection of objects to be deleted. If the call is
- the result of a cascade, 'source' should be the model that caused it
- and 'nullable' should be set to True, if the relation can be null.
+ the result of a cascade, 'source' should be the model that caused it,
+ and 'nullable' should be set to True if the relation can be null.
Returns a list of all objects that were not already collected.
"""
@@ -99,7 +99,7 @@ class Collector(object):
# Nullable relationships can be ignored -- they are nulled out before
# deleting, and therefore do not affect the order in which objects have
# to be deleted.
- if new_objs and source is not None and not nullable:
+ if source is not None and not nullable:
if reverse_dependency:
source, model = model, source
self.dependencies.setdefault(source, set()).add(model)
diff --git a/tests/regressiontests/delete_regress/models.py b/tests/regressiontests/delete_regress/models.py
index 5c77117719..8e3d0d55b1 100644
--- a/tests/regressiontests/delete_regress/models.py
+++ b/tests/regressiontests/delete_regress/models.py
@@ -51,3 +51,19 @@ class Food(models.Model):
class Eaten(models.Model):
food = models.ForeignKey(Food, to_field="name")
meal = models.CharField(max_length=20)
+
+
+# Models for #15776
+
+class Policy(models.Model):
+ policy_number = models.CharField(max_length=10)
+
+class Version(models.Model):
+ policy = models.ForeignKey(Policy)
+
+class Location(models.Model):
+ version = models.ForeignKey(Version, blank=True, null=True)
+
+class Item(models.Model):
+ version = models.ForeignKey(Version)
+ location = models.ForeignKey(Location, blank=True, null=True)
diff --git a/tests/regressiontests/delete_regress/tests.py b/tests/regressiontests/delete_regress/tests.py
index 20b9382c31..2027780329 100644
--- a/tests/regressiontests/delete_regress/tests.py
+++ b/tests/regressiontests/delete_regress/tests.py
@@ -5,7 +5,8 @@ from django.db import backend, connection, transaction, DEFAULT_DB_ALIAS
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
from models import (Book, Award, AwardNote, Person, Child, Toy, PlayedWith,
- PlayedWithNote, Contact, Email, Researcher, Food, Eaten)
+ PlayedWithNote, Contact, Email, Researcher, Food, Eaten,
+ Policy, Version, Location, Item)
# Can't run this test under SQLite, because you can't
@@ -102,6 +103,13 @@ class DeleteCascadeTests(TestCase):
# first two asserts just sanity checks, this is the kicker:
self.assertEqual(PlayedWithNote.objects.count(), 0)
+ def test_15776(self):
+ policy = Policy.objects.create(pk=1, policy_number="1234")
+ version = Version.objects.create(policy=policy)
+ location = Location.objects.create(version=version)
+ item = Item.objects.create(version=version, location=location)
+ policy.delete()
+
class DeleteCascadeTransactionTests(TransactionTestCase):
def test_inheritance(self):