From ffe755e990fa7e680960c7a413d387a79f194204 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 5 Aug 2015 15:52:11 -0400 Subject: [PATCH] [1.8.x] Fixed #24951 -- Fixed AssertionError in delete queries involving a foreign/primary key. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks Anssi Kääriäinen for help. Backport of 333cbdcd2de4546e33ad50ebd8b67e1a1e87aeec from master --- django/db/models/sql/compiler.py | 2 +- docs/releases/1.8.5.txt | 3 ++- tests/one_to_one/models.py | 2 +- tests/one_to_one/tests.py | 8 +++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 688e3f741e..fed4353a3a 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -986,7 +986,7 @@ class SQLDeleteCompiler(SQLCompiler): Creates the SQL for this query. Returns the SQL string and list of parameters. """ - assert len(self.query.tables) == 1, \ + assert len([t for t in self.query.tables if self.query.alias_refcount[t] > 0]) == 1, \ "Can only delete from one table at a time." qn = self.quote_name_unless_alias result = ['DELETE FROM %s' % qn(self.query.tables[0])] diff --git a/docs/releases/1.8.5.txt b/docs/releases/1.8.5.txt index 43a959197b..df7783f4df 100644 --- a/docs/releases/1.8.5.txt +++ b/docs/releases/1.8.5.txt @@ -9,4 +9,5 @@ Django 1.8.5 fixes several bugs in 1.8.4. Bugfixes ======== -* ... +* Fixed ``AssertionError`` in some delete queries with a model containing a + field that is both a foreign and primary key (:ticket:`24951`). diff --git a/tests/one_to_one/models.py b/tests/one_to_one/models.py index 8a5defe856..a71e65a0f9 100644 --- a/tests/one_to_one/models.py +++ b/tests/one_to_one/models.py @@ -83,7 +83,7 @@ class MultiModel(models.Model): class Target(models.Model): - pass + name = models.CharField(max_length=50) class Pointer(models.Model): diff --git a/tests/one_to_one/tests.py b/tests/one_to_one/tests.py index 94a6ad957e..b71ee0645a 100644 --- a/tests/one_to_one/tests.py +++ b/tests/one_to_one/tests.py @@ -5,7 +5,8 @@ from django.test import TestCase from .models import ( Bar, Director, Favorites, HiddenPointer, ManualPrimaryKey, MultiModel, - Place, RelatedModel, Restaurant, School, Target, UndergroundBar, Waiter, + Place, Pointer, RelatedModel, Restaurant, School, Target, UndergroundBar, + Waiter, ) @@ -256,6 +257,11 @@ class OneToOneTests(TestCase): [] ) + def test_o2o_primary_key_delete(self): + t = Target.objects.create(name='name') + Pointer.objects.create(other=t) + Pointer.objects.filter(other__name='name').delete() + def test_reverse_object_does_not_exist_cache(self): """ Regression for #13839 and #17439.