Fixed #24951 -- Fixed AssertionError in delete queries involving a foreign/primary key.

Thanks Anssi Kääriäinen for help.
This commit is contained in:
Tim Graham 2015-08-05 15:52:11 -04:00
parent 1b8d7eff3b
commit 333cbdcd2d
4 changed files with 13 additions and 4 deletions

View File

@ -995,7 +995,7 @@ class SQLDeleteCompiler(SQLCompiler):
Creates the SQL for this query. Returns the SQL string and list of Creates the SQL for this query. Returns the SQL string and list of
parameters. 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." "Can only delete from one table at a time."
qn = self.quote_name_unless_alias qn = self.quote_name_unless_alias
result = ['DELETE FROM %s' % qn(self.query.tables[0])] result = ['DELETE FROM %s' % qn(self.query.tables[0])]

View File

@ -9,4 +9,5 @@ Django 1.8.5 fixes several bugs in 1.8.4.
Bugfixes Bugfixes
======== ========
* ... * Fixed ``AssertionError`` in some delete queries with a model containing a
field that is both a foreign and primary key (:ticket:`24951`).

View File

@ -83,7 +83,7 @@ class MultiModel(models.Model):
class Target(models.Model): class Target(models.Model):
pass name = models.CharField(max_length=50)
class Pointer(models.Model): class Pointer(models.Model):

View File

@ -5,7 +5,8 @@ from django.test import TestCase
from .models import ( from .models import (
Bar, Director, Favorites, HiddenPointer, ManualPrimaryKey, MultiModel, Bar, Director, Favorites, HiddenPointer, ManualPrimaryKey, MultiModel,
Place, RelatedModel, Restaurant, School, Target, UndergroundBar, Waiter, Place, Pointer, RelatedModel, Restaurant, School, Target, UndergroundBar,
Waiter,
) )
@ -256,6 +257,13 @@ class OneToOneTests(TestCase):
[] []
) )
def test_o2o_primary_key_delete(self):
t = Target.objects.create(name='name')
Pointer.objects.create(other=t)
num_deleted, objs = Pointer.objects.filter(other__name='name').delete()
self.assertEqual(num_deleted, 1)
self.assertEqual(objs, {'one_to_one.Pointer': 1})
def test_reverse_object_does_not_exist_cache(self): def test_reverse_object_does_not_exist_cache(self):
""" """
Regression for #13839 and #17439. Regression for #13839 and #17439.